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,24 +1,49 @@
{ {
"configurations": [ "configurations": [
{ {
"name": "Linux", "name": "Mac",
"includePath": [ "includePath": ["${default}"],
"${workspaceFolder}/**", "defines": [],
"${WUT_ROOT}/include", "macFrameworkPath": [
"../librw" "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
], ],
"defines": [ "compilerPath": "/opt/local/bin/clang",
"__WIIU__", "compilerArgs": ["-g"],
"__WUT__", "cStandard": "gnu11",
"LIBRW",
"AUDIO_OAL",
"BIGENDIAN",
"__FILENAME__=\"a\""
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu18",
"cppStandard": "gnu++14", "cppStandard": "gnu++14",
"intelliSenseMode": "gcc-x64" "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 "version": 4

101
.vscode/settings.json vendored
View File

@ -1,69 +1,36 @@
{ {
"files.associations": { "C_Cpp.default.cStandard": "gnu11",
"*.utheme": "ini", "C_Cpp.default.cppStandard": "gnu++14",
"chrono": "cpp", "C_Cpp.default.includePath": [
"random": "cpp", "src",
"limits": "cpp", "src/animation",
"valarray": "cpp", "src/audio",
"*.tcc": "cpp", "src/audio/eax",
"fstream": "cpp", "src/audio/oal",
"memory_resource": "cpp", "src/buildings",
"*.idl": "cpp", "src/collision",
"array": "cpp", "src/control",
"string_view": "cpp", "src/core",
"initializer_list": "cpp", "src/entities",
"utility": "cpp", "src/extras",
"typeinfo": "cpp", "src/fakerw",
"cmath": "cpp", "src/math",
"string": "cpp", "src/modelinfo",
"cctype": "cpp", "src/objects",
"clocale": "cpp", "src/peds",
"csignal": "cpp", "src/renderer",
"cstdarg": "cpp", "src/rw",
"cstddef": "cpp", "src/save",
"cstdio": "cpp", "src/save/glfw",
"cstdlib": "cpp", "src/skel",
"cstring": "cpp", "src/text",
"ctime": "cpp", "src/vehicles",
"cwchar": "cpp", "src/weapons",
"cwctype": "cpp", "vendor/librw"
"atomic": "cpp", ],
"bit": "cpp", "C_Cpp.vcFormat.indent.gotoLabels": "leftmostColumn",
"bitset": "cpp", "C_Cpp.vcFormat.space.pointerReferenceAlignment": "right",
"complex": "cpp", "cSpell.enabled": false,
"condition_variable": "cpp", "files.trimFinalNewlines": false,
"cstdint": "cpp", "files.trimTrailingWhitespace": false
"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"
}
} }

View File

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

View File

@ -1,5 +1,5 @@
# reVC-wiiu # 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. 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) if(NOT TARGET MilesSDK::MilesSDK)
add_library(MilesSDK::MilesSDK UNKNOWN IMPORTED) add_library(MilesSDK::MilesSDK UNKNOWN IMPORTED)
set_target_properties(MilesSDK::MilesSDK PROPERTIES set_target_properties(MilesSDK::MilesSDK PROPERTIES
IMPORTED_LOCATION "${MilesSDK_LIBRARIES} IMPORTED_LOCATION "${MilesSDK_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${MilesSDK_INCLUDE_DIR}" INTERFACE_INCLUDE_DIRECTORIES "${MilesSDK_INCLUDE_DIR}"
) )
endif() endif()

View File

@ -18,7 +18,7 @@ find_path(mpg123_INCLUDE_DIR mpg123.h
PATH_SUFFIXES include 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} HINTS ${PKG_MPG123_LIBRARIES}
PATHS "${mpg123_DIR}" PATHS "${mpg123_DIR}"
PATH_SUFFIXES lib 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> <FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS> <FILEFLAGS></FILEFLAGS>
</FILE> </FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE> <FILE>
<PATHTYPE>Name</PATHTYPE> <PATHTYPE>Name</PATHTYPE>
<PATH>Script.cpp</PATH> <PATH>Script.cpp</PATH>
@ -4711,6 +4718,11 @@
<PATH>SceneEdit.h</PATH> <PATH>SceneEdit.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT> <PATHFORMAT>Windows</PATHFORMAT>
</FILEREF> </FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF> <FILEREF>
<PATHTYPE>Name</PATHTYPE> <PATHTYPE>Name</PATHTYPE>
<PATH>Script.cpp</PATH> <PATH>Script.cpp</PATH>
@ -8248,6 +8260,13 @@
<FILEKIND>Text</FILEKIND> <FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS> <FILEFLAGS></FILEFLAGS>
</FILE> </FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE> <FILE>
<PATHTYPE>Name</PATHTYPE> <PATHTYPE>Name</PATHTYPE>
<PATH>Script.cpp</PATH> <PATH>Script.cpp</PATH>
@ -11236,6 +11255,11 @@
<PATH>SceneEdit.h</PATH> <PATH>SceneEdit.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT> <PATHFORMAT>Windows</PATHFORMAT>
</FILEREF> </FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF> <FILEREF>
<PATHTYPE>Name</PATHTYPE> <PATHTYPE>Name</PATHTYPE>
<PATH>Script.cpp</PATH> <PATH>Script.cpp</PATH>
@ -13780,6 +13804,12 @@
<PATH>SceneEdit.h</PATH> <PATH>SceneEdit.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT> <PATHFORMAT>Windows</PATHFORMAT>
</FILEREF> </FILEREF>
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>ScriptDebug.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF> <FILEREF>
<TARGETNAME>Debug</TARGETNAME> <TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE> <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" description = "Don't print full paths into binary"
} }
require("autoconf")
if(_OPTIONS["with-librw"]) then if(_OPTIONS["with-librw"]) then
Librw = "vendor/librw" Librw = "vendor/librw"
else else
@ -365,6 +367,19 @@ project "reVC"
filter "platforms:win*glfw*" filter "platforms:win*glfw*"
staticruntime "off" 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" filter "platforms:win*oal"
includedirs { "vendor/openal-soft/include" } includedirs { "vendor/openal-soft/include" }
includedirs { "vendor/libsndfile/include" } includedirs { "vendor/libsndfile/include" }
@ -381,10 +396,10 @@ project "reVC"
libdirs { "vendor/openal-soft/libs/Win64" } libdirs { "vendor/openal-soft/libs/Win64" }
filter "platforms:linux*oal" filter "platforms:linux*oal"
links { "openal", "mpg123", "sndfile", "pthread", "X11" } links { "openal", "mpg123", "sndfile", "pthread" }
filter "platforms:bsd*oal" filter "platforms:bsd*oal"
links { "openal", "mpg123", "sndfile", "pthread", "X11" } links { "openal", "mpg123", "sndfile", "pthread" }
filter "platforms:macosx*oal" filter "platforms:macosx*oal"
links { "openal", "mpg123", "sndfile", "pthread" } 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") if(${PROJECT}_AUDIO STREQUAL "OAL")
find_package(OpenAL REQUIRED) find_package(OpenAL REQUIRED)
if(TARGET OpenAL::OpenAL)
target_link_libraries(${EXECUTABLE} PRIVATE OpenAL::OpenAL)
else()
target_include_directories(${EXECUTABLE} PRIVATE ${OPENAL_INCLUDE_DIR}) target_include_directories(${EXECUTABLE} PRIVATE ${OPENAL_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE} PRIVATE ${OPENAL_LIBRARY}) target_link_libraries(${EXECUTABLE} PRIVATE ${OPENAL_LIBRARY})
target_compile_definitions(${EXECUTABLE} PRIVATE ${OPENAL_DEFINITIONS}) target_compile_definitions(${EXECUTABLE} PRIVATE ${OPENAL_DEFINITIONS})
endif()
target_compile_definitions(${EXECUTABLE} PRIVATE AUDIO_OAL) target_compile_definitions(${EXECUTABLE} PRIVATE AUDIO_OAL)
elseif(${PROJECT}_AUDIO STREQUAL "MSS") elseif(${PROJECT}_AUDIO STREQUAL "MSS")
find_package(MilesSDK REQUIRED) find_package(MilesSDK REQUIRED)
@ -120,13 +124,35 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
) )
endif() 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} set_target_properties(${EXECUTABLE}
PROPERTIES PROPERTIES
C_STANDARD 11 C_STANDARD 11
C_EXTENSIONS OFF C_EXTENSIONS ${${PROJECT}_C_CXX_EXTENSIONS}
C_STANDARD_REQUIRED ON C_STANDARD_REQUIRED ON
CXX_STANDARD 11 CXX_STANDARD 11
CXX_EXTENSIONS OFF CXX_EXTENSIONS ${${PROJECT}_C_CXX_EXTENSIONS}
CXX_STANDARD_REQUIRED ON CXX_STANDARD_REQUIRED ON
) )
@ -140,3 +166,5 @@ if(${PROJECT}_INSTALL)
install(FILES $<TARGET_PDB_FILE:${EXECUTABLE}> DESTINATION "." OPTIONAL) install(FILES $<TARGET_PDB_FILE:${EXECUTABLE}> DESTINATION "." OPTIONAL)
endif() endif()
endif() endif()
reVC_platform_target(${EXECUTABLE} INSTALL)

View File

@ -10,20 +10,39 @@
const int CollisionSoundIntensity = 60; 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; float distSquared;
m_sQueue.m_pEntity2 = nil; CVector v1;
m_sQueue.m_bSurface1 = SURFACE_DEFAULT; CVector v2;
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);
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++) if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_nUserPause ||
m_bIndicesTable[i] = NUMAUDIOCOLLISIONS; (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 void
@ -55,135 +74,71 @@ cAudioCollisionManager::AddCollisionToRequestedQueue()
m_bIndicesTable[i] = collisionsIndex; 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 void
cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter) cAudioManager::ServiceCollisions()
{ {
bool8 distCalculated = FALSE; int i, j;
if(col.m_fIntensity2 > 0.0016f) { bool8 abRepeatedCollision1[NUMAUDIOCOLLISIONS];
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col); bool8 abRepeatedCollision2[NUMAUDIOCOLLISIONS];
if(emittingVol) {
CalculateDistance(distCalculated, m_sQueueSample.m_fDistance); m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume) { for(int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_sQueueSample.m_nCounter = counter; abRepeatedCollision1[i] = abRepeatedCollision2[i] = FALSE;
m_sQueueSample.m_vecPos = col.m_vecPosition;
m_sQueueSample.m_nBankIndex = SFX_BANK_0; for(i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
m_sQueueSample.m_bIs2D = FALSE; for(j = 0; j < NUMAUDIOCOLLISIONS; j++) {
m_sQueueSample.m_nReleasingVolumeModificator = 7; int index = m_sCollisionManager.m_bIndicesTable[i];
m_sQueueSample.m_nLoopCount = 0; if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
m_sQueueSample.m_nEmittingVolume = emittingVol; && (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex) && (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
m_sQueueSample.m_fSpeedMultiplier = 4.0f; && (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity; ) {
m_sQueueSample.m_bReleasingSoundFlag = FALSE; abRepeatedCollision1[index] = TRUE;
m_sQueueSample.m_nReleasingVolumeDivider = 5; abRepeatedCollision2[j] = TRUE;
m_sQueueSample.m_bReverbFlag = TRUE; m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
m_sQueueSample.m_bRequireReflection = FALSE; SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
AddSampleToRequestedQueue(); 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, static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
SFX_COL_TARMAC_1, SFX_COL_TARMAC_1,
SFX_COL_GRASS_1, SFX_COL_GRASS_1,
@ -223,9 +178,8 @@ static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
void void
cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col) cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
{ {
uint16 s1;
int16 s1; uint16 s2;
int16 s2;
int32 emittingVol; int32 emittingVol;
float ratio; float ratio;
@ -251,7 +205,7 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance); m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance);
m_sQueueSample.m_nVolume = m_sQueueSample.m_nVolume =
ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance); ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume) { if(m_sQueueSample.m_nVolume > 0) {
m_sQueueSample.m_nSampleIndex = gOneShotCol[s1]; m_sQueueSample.m_nSampleIndex = gOneShotCol[s1];
switch(m_sQueueSample.m_nSampleIndex) { switch(m_sQueueSample.m_nSampleIndex) {
case SFX_COL_TARMAC_1: case SFX_COL_TARMAC_1:
@ -311,13 +265,13 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
m_sQueueSample.m_bIs2D = FALSE; m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 11; m_sQueueSample.m_nReleasingVolumeModificator = 11;
m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nEmittingVolume = emittingVol; SET_EMITTING_VOLUME(emittingVol);
RESET_LOOP_OFFSETS RESET_LOOP_OFFSETS
m_sQueueSample.m_fSpeedMultiplier = 4.0f; m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity; m_sQueueSample.m_SoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_bReleasingSoundFlag = TRUE; m_sQueueSample.m_bReleasingSoundFlag = TRUE;
m_sQueueSample.m_bReverbFlag = TRUE; SET_SOUND_REVERB(TRUE);
m_sQueueSample.m_bRequireReflection = FALSE; SET_SOUND_REFLECTION(FALSE);
AddSampleToRequestedQueue(); AddSampleToRequestedQueue();
} }
} }
@ -325,100 +279,129 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
} }
void void
cAudioManager::ServiceCollisions() cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
{ {
int i, j; bool8 distCalculated = FALSE;
bool8 abRepeatedCollision1[NUMAUDIOCOLLISIONS]; if(col.m_fIntensity2 > 0.0016f) {
bool8 abRepeatedCollision2[NUMAUDIOCOLLISIONS]; uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
if(emittingVol) {
m_sQueueSample.m_nEntityIndex = m_nCollisionEntity; CalculateDistance(distCalculated, m_sQueueSample.m_fDistance);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++) abRepeatedCollision1[i] = abRepeatedCollision2[i] = FALSE; if(m_sQueueSample.m_nVolume > 0) {
m_sQueueSample.m_nCounter = counter;
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) { m_sQueueSample.m_vecPos = col.m_vecPosition;
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) { m_sQueueSample.m_nBankIndex = SFX_BANK_0;
int index = m_sCollisionManager.m_bIndicesTable[i]; m_sQueueSample.m_bIs2D = FALSE;
if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1) m_sQueueSample.m_nReleasingVolumeModificator = 7;
&& (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2) m_sQueueSample.m_nLoopCount = 0;
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1) SET_EMITTING_VOLUME(emittingVol);
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2) SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
) { m_sQueueSample.m_fSpeedMultiplier = 4.0f;
abRepeatedCollision1[index] = TRUE; m_sQueueSample.m_SoundIntensity = CollisionSoundIntensity;
abRepeatedCollision2[j] = TRUE; m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume; m_sQueueSample.m_nReleasingVolumeDivider = 5;
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j); SET_SOUND_REVERB(TRUE);
break; 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 uint32
cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision)
float velocity)
{ {
float distSquared; uint8 surface1 = audioCollision.m_bSurface1;
CVector v1; uint8 surface2 = audioCollision.m_bSurface2;
CVector v2; int32 vol;
float ratio;
if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_nUserPause || if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE ||
(velocity < 0.0016f && collisionPower < 0.01f)) surface2 == SURFACE_HEDGE) {
return; ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_RAIN;
if(entity1->IsBuilding()) { m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000;
v1 = v2 = entity2->GetPosition(); vol = 50.f * ratio;
} else if(entity2->IsBuilding()) { } else if(surface1 == SURFACE_WATER || surface2 == SURFACE_WATER) {
v1 = v2 = entity1->GetPosition(); 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 { } else {
v1 = entity1->GetPosition(); ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
v2 = entity2->GetPosition(); m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1;
} m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000;
CVector pos = (v1 + v2) * 0.5f; vol = 40.f * ratio;
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();
} }
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; float m_fDistance;
int32 m_nBaseVolume; 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); VALIDATE_SIZE(cAudioCollision, 40);
@ -31,7 +42,15 @@ public:
uint8 m_bCollisionsInQueue; uint8 m_bCollisionsInQueue;
cAudioCollision m_sQueue; cAudioCollision m_sQueue;
cAudioCollisionManager(); cAudioCollisionManager()
{
m_sQueue.Reset();
for(int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
m_bCollisionsInQueue = 0;
}
void AddCollisionToRequestedQueue(); void AddCollisionToRequestedQueue();
}; };

File diff suppressed because it is too large Load Diff

View File

@ -31,8 +31,10 @@ cAudioManager::cAudioManager()
ClearRequestedQueue(); ClearRequestedQueue();
ClearActiveSamples(); ClearActiveSamples();
GenerateIntegerRandomNumberTable(); GenerateIntegerRandomNumberTable();
field_4 = 0; m_bDoubleVolume = FALSE;
#ifdef AUDIO_REFLECTIONS
m_bDynamicAcousticModelingStatus = TRUE; m_bDynamicAcousticModelingStatus = TRUE;
#endif
for (int i = 0; i < NUM_AUDIOENTITIES; i++) { for (int i = 0; i < NUM_AUDIOENTITIES; i++) {
m_asAudioEntities[i].m_bIsUsed = FALSE; m_asAudioEntities[i].m_bIsUsed = FALSE;
@ -58,11 +60,16 @@ cAudioManager::Initialise()
PreInitialiseGameSpecificSetup(); PreInitialiseGameSpecificSetup();
m_bIsInitialised = SampleManager.Initialise(); m_bIsInitialised = SampleManager.Initialise();
if (m_bIsInitialised) { if (m_bIsInitialised) {
#ifdef EXTERNAL_3D_SOUND
m_nActiveSamples = SampleManager.GetMaximumSupportedChannels(); m_nActiveSamples = SampleManager.GetMaximumSupportedChannels();
if (m_nActiveSamples <= 1) { if (m_nActiveSamples <= 1) {
Terminate(); Terminate();
} else { } else {
--m_nActiveSamples; --m_nActiveSamples;
#else
{
m_nActiveSamples = NUM_CHANNELS_GENERIC;
#endif
PostInitialiseGameSpecificSetup(); PostInitialiseGameSpecificSetup();
InitialisePoliceRadioZones(); InitialisePoliceRadioZones();
InitialisePoliceRadio(); InitialisePoliceRadio();
@ -111,7 +118,9 @@ cAudioManager::Service()
if (m_bIsInitialised) { if (m_bIsInitialised) {
m_nPreviousUserPause = m_nUserPause; m_nPreviousUserPause = m_nUserPause;
m_nUserPause = CTimer::GetIsUserPaused(); m_nUserPause = CTimer::GetIsUserPaused();
#ifdef AUDIO_REFLECTIONS
UpdateReflections(); UpdateReflections();
#endif
ServiceSoundEffects(); ServiceSoundEffects();
MusicManager.Service(); 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 void
cAudioManager::SetEntityStatus(int32 id, bool8 status) cAudioManager::SetEntityStatus(int32 id, bool8 status)
{ {
@ -167,6 +184,14 @@ cAudioManager::SetEntityStatus(int32 id, bool8 status)
m_asAudioEntities[id].m_bStatus = 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 void
cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol) cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol)
{ {
@ -218,39 +243,39 @@ cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol)
} }
void void
cAudioManager::SetMP3BoostVolume(uint8 volume) const cAudioManager::SetEffectsMasterVolume(uint8 volume)
{
SampleManager.SetMP3BoostVolume(volume);
}
void
cAudioManager::SetEffectsMasterVolume(uint8 volume) const
{ {
SampleManager.SetEffectsMasterVolume(volume); SampleManager.SetEffectsMasterVolume(volume);
} }
void void
cAudioManager::SetMusicMasterVolume(uint8 volume) const cAudioManager::SetMusicMasterVolume(uint8 volume)
{ {
SampleManager.SetMusicMasterVolume(volume); SampleManager.SetMusicMasterVolume(volume);
} }
void void
cAudioManager::SetEffectsFadeVol(uint8 volume) const cAudioManager::SetMP3BoostVolume(uint8 volume)
{
SampleManager.SetMP3BoostVolume(volume);
}
void
cAudioManager::SetEffectsFadeVol(uint8 volume)
{ {
SampleManager.SetEffectsFadeVolume(volume); SampleManager.SetEffectsFadeVolume(volume);
} }
void void
cAudioManager::SetMonoMode(bool8 mono) cAudioManager::SetMusicFadeVol(uint8 volume)
{ {
SampleManager.SetMonoMode(mono); SampleManager.SetMusicFadeVolume(volume);
} }
void 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 void
@ -317,17 +342,24 @@ cAudioManager::DestroyAllGameCreatedEntities()
} }
} }
#ifdef GTA_PC
uint8 uint8
cAudioManager::GetNum3DProvidersAvailable() const cAudioManager::GetNum3DProvidersAvailable()
{ {
#ifdef EXTERNAL_3D_SOUND
if (m_bIsInitialised) if (m_bIsInitialised)
return SampleManager.GetNum3DProvidersAvailable(); return SampleManager.GetNum3DProvidersAvailable();
#endif
return 0; return 0;
} }
char * char *
cAudioManager::Get3DProviderName(uint8 id) const cAudioManager::Get3DProviderName(uint8 id)
{ {
#ifndef EXTERNAL_3D_SOUND
return nil;
#else
if (!m_bIsInitialised) if (!m_bIsInitialised)
return nil; return nil;
#ifdef AUDIO_OAL #ifdef AUDIO_OAL
@ -338,22 +370,27 @@ cAudioManager::Get3DProviderName(uint8 id) const
return nil; return nil;
#endif #endif
return SampleManager.Get3DProviderName(id); return SampleManager.Get3DProviderName(id);
#endif
} }
int8 int8
cAudioManager::GetCurrent3DProviderIndex() const cAudioManager::GetCurrent3DProviderIndex()
{ {
#ifdef EXTERNAL_3D_SOUND
if (m_bIsInitialised) if (m_bIsInitialised)
return SampleManager.GetCurrent3DProviderIndex(); return SampleManager.GetCurrent3DProviderIndex();
#endif
return -1; return -1;
} }
int8 int8
cAudioManager::AutoDetect3DProviders() const cAudioManager::AutoDetect3DProviders()
{ {
#ifdef EXTERNAL_3D_SOUND
if (m_bIsInitialised) if (m_bIsInitialised)
return SampleManager.AutoDetect3DProviders(); return SampleManager.AutoDetect3DProviders();
#endif
return -1; return -1;
} }
@ -361,6 +398,9 @@ cAudioManager::AutoDetect3DProviders() const
int8 int8
cAudioManager::SetCurrent3DProvider(uint8 which) cAudioManager::SetCurrent3DProvider(uint8 which)
{ {
#ifndef EXTERNAL_3D_SOUND
return -1;
#else
if (!m_bIsInitialised) if (!m_bIsInitialised)
return -1; return -1;
for (uint8 i = 0; i < m_nActiveSamples + 1; ++i) for (uint8 i = 0; i < m_nActiveSamples + 1; ++i)
@ -379,16 +419,19 @@ cAudioManager::SetCurrent3DProvider(uint8 which)
--m_nActiveSamples; --m_nActiveSamples;
} }
return current; return current;
#endif
} }
void void
cAudioManager::SetSpeakerConfig(int32 conf) const cAudioManager::SetSpeakerConfig(int32 conf)
{ {
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetSpeakerConfig(conf); SampleManager.SetSpeakerConfig(conf);
#endif
} }
bool8 bool8
cAudioManager::IsMP3RadioChannelAvailable() const cAudioManager::IsMP3RadioChannelAvailable()
{ {
if (m_bIsInitialised) if (m_bIsInitialised)
return SampleManager.IsMP3RadioChannelAvailable(); return SampleManager.IsMP3RadioChannelAvailable();
@ -397,7 +440,7 @@ cAudioManager::IsMP3RadioChannelAvailable() const
} }
void void
cAudioManager::ReleaseDigitalHandle() const cAudioManager::ReleaseDigitalHandle()
{ {
if (m_bIsInitialised) { if (m_bIsInitialised) {
SampleManager.ReleaseDigitalHandle(); SampleManager.ReleaseDigitalHandle();
@ -405,38 +448,43 @@ cAudioManager::ReleaseDigitalHandle() const
} }
void void
cAudioManager::ReacquireDigitalHandle() const cAudioManager::ReacquireDigitalHandle()
{ {
if (m_bIsInitialised) { if (m_bIsInitialised) {
SampleManager.ReacquireDigitalHandle(); SampleManager.ReacquireDigitalHandle();
} }
} }
#ifdef AUDIO_REFLECTIONS
void void
cAudioManager::SetDynamicAcousticModelingStatus(bool8 status) cAudioManager::SetDynamicAcousticModelingStatus(bool8 status)
{ {
m_bDynamicAcousticModelingStatus = status; m_bDynamicAcousticModelingStatus = status;
} }
#endif
bool8 bool8
cAudioManager::CheckForAnAudioFileOnCD() const cAudioManager::CheckForAnAudioFileOnCD()
{ {
return SampleManager.CheckForAnAudioFileOnCD(); return SampleManager.CheckForAnAudioFileOnCD();
} }
char char
cAudioManager::GetCDAudioDriveLetter() const cAudioManager::GetCDAudioDriveLetter()
{ {
if(m_bIsInitialised) return SampleManager.GetCDAudioDriveLetter(); if (m_bIsInitialised)
return SampleManager.GetCDAudioDriveLetter();
return '\0'; return '\0';
} }
bool8 bool8
cAudioManager::IsAudioInitialised() const cAudioManager::IsAudioInitialised()
{ {
return m_bIsInitialised; return m_bIsInitialised;
} }
#endif // GTA_PC
void void
cAudioManager::ServiceSoundEffects() cAudioManager::ServiceSoundEffects()
{ {
@ -461,7 +509,9 @@ cAudioManager::ServiceSoundEffects()
ClearActiveSamples(); ClearActiveSamples();
} }
m_nActiveSampleQueue = m_nActiveSampleQueue == 1 ? 0 : 1; m_nActiveSampleQueue = m_nActiveSampleQueue == 1 ? 0 : 1;
#ifdef AUDIO_REVERB
if(m_bReverb) ProcessReverb(); if(m_bReverb) ProcessReverb();
#endif
ProcessSpecial(); ProcessSpecial();
ClearRequestedQueue(); ClearRequestedQueue();
InterrogateAudioEntities(); InterrogateAudioEntities();
@ -470,7 +520,7 @@ cAudioManager::ServiceSoundEffects()
ServiceCollisions(); ServiceCollisions();
AddReleasingSounds(); AddReleasingSounds();
ProcessMissionAudio(); ProcessMissionAudio();
#ifdef GTA_PC #ifdef EXTERNAL_3D_SOUND
AdjustSamplesVolume(); AdjustSamplesVolume();
#endif #endif
ProcessActiveQueues(); ProcessActiveQueues();
@ -487,7 +537,7 @@ cAudioManager::ServiceSoundEffects()
} }
uint8 uint8
cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance)
{ {
float newSoundIntensity; float newSoundIntensity;
float newEmittingVolume; float newEmittingVolume;
@ -501,29 +551,42 @@ cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float d
newEmittingVolume = emittingVolume * SQR((soundIntensity - newSoundIntensity - (distance - newSoundIntensity)) newEmittingVolume = emittingVolume * SQR((soundIntensity - newSoundIntensity - (distance - newSoundIntensity))
/ (soundIntensity - newSoundIntensity)); / (soundIntensity - newSoundIntensity));
return Min(127u, newEmittingVolume); return Min(127, newEmittingVolume);
} }
void void
cAudioManager::TranslateEntity(Const CVector *in, CVector *out) const cAudioManager::TranslateEntity(Const CVector *in, CVector *out)
{ {
*out = MultiplyInverse(TheCamera.GetMatrix(), *in); *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 int32
cAudioManager::ComputePan(float dist, CVector *vec) 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, int32 index = vec->x / (dist / 64.f);
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}; index = Min(63, ABS(index));
int32 index = Min(63, Abs(int32(vec->x / (dist / 64.f))));
if (vec->x > 0.f) if (vec->x > 0.f)
return Max(20, 63 - PanTable[index]); return Max(20, 63 - (int8)PanTable[index]);
return Min(107, PanTable[index] + 63); return Min(107, PanTable[index] + 63);
} }
uint32 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; uint32 newFreq = oldFreq;
if (!TheCamera.Get_Just_Switched_Status() && speedMultiplier != 0.0f) { if (!TheCamera.Get_Just_Switched_Status() && speedMultiplier != 0.0f) {
@ -540,7 +603,7 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
} }
int32 int32
cAudioManager::RandomDisplacement(uint32 seed) const cAudioManager::RandomDisplacement(uint32 seed)
{ {
int32 value; int32 value;
@ -573,9 +636,11 @@ cAudioManager::InterrogateAudioEntities()
void void
cAudioManager::AddSampleToRequestedQueue() cAudioManager::AddSampleToRequestedQueue()
{ {
int32 calculatedVolume; uint32 calculatedVolume;
uint8 sampleIndex; uint8 sampleIndex;
#ifdef AUDIO_REFLECTIONS
bool8 bReflections; bool8 bReflections;
#endif
if (m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) { if (m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) {
calculatedVolume = m_sQueueSample.m_nReleasingVolumeModificator * (MAX_VOLUME - m_sQueueSample.m_nVolume); 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_nCalculatedVolume = calculatedVolume;
m_sQueueSample.m_bLoopEnded = FALSE; m_sQueueSample.m_bLoopEnded = FALSE;
#ifdef AUDIO_REFLECTIONS
if (m_sQueueSample.m_bIs2D || CCullZones::InRoomForAudio()) { if (m_sQueueSample.m_bIs2D || CCullZones::InRoomForAudio()) {
m_sQueueSample.m_bRequireReflection = FALSE; m_sQueueSample.m_bRequireReflection = FALSE;
m_sQueueSample.m_nLoopsRemaining = 0; 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; bReflections = m_sQueueSample.m_bRequireReflection;
} else { } else {
bReflections = FALSE; bReflections = FALSE;
@ -602,23 +668,28 @@ cAudioManager::AddSampleToRequestedQueue()
m_sQueueSample.m_bRequireReflection = FALSE; m_sQueueSample.m_bRequireReflection = FALSE;
if ( m_bReverb && m_sQueueSample.m_bIs2D ) if ( m_bReverb && m_sQueueSample.m_bIs2D )
m_sQueueSample.field_4C = 30; m_sQueueSample.m_nFrontRearOffset = 30;
#ifdef AUDIO_REVERB
if (!m_bDynamicAcousticModelingStatus) if (!m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bReverbFlag = FALSE; m_sQueueSample.m_bReverbFlag = FALSE;
#endif
#endif
m_asSamples[m_nActiveSampleQueue][sampleIndex] = m_sQueueSample; m_asSamples[m_nActiveSampleQueue][sampleIndex] = m_sQueueSample;
AddDetailsToRequestedOrderList(sampleIndex); AddDetailsToRequestedOrderList(sampleIndex);
#ifdef AUDIO_REFLECTIONS
if (bReflections) if (bReflections)
AddReflectionsToRequestedQueue(); AddReflectionsToRequestedQueue();
#endif
} }
} }
void void
cAudioManager::AddDetailsToRequestedOrderList(uint8 sample) cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
{ {
uint32 i = 0; uint32 i = 0;
if (sample != 0) { if (sample > 0) {
for (; i < sample; i++) { for (; i < sample; i++) {
if (m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]].m_nCalculatedVolume > if (m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]].m_nCalculatedVolume >
m_asSamples[m_nActiveSampleQueue][sample].m_nCalculatedVolume) m_asSamples[m_nActiveSampleQueue][sample].m_nCalculatedVolume)
@ -631,6 +702,7 @@ cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = sample; m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = sample;
} }
#ifdef AUDIO_REFLECTIONS
void void
cAudioManager::AddReflectionsToRequestedQueue() cAudioManager::AddReflectionsToRequestedQueue()
{ {
@ -652,33 +724,33 @@ cAudioManager::AddReflectionsToRequestedQueue()
} else { } else {
emittingVolume = (9 * m_sQueueSample.m_nVolume) / 16; 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++) { for (uint32 i = 0; i < ARRAY_SIZE(m_afReflectionsDistances); i++) {
if ( CTimer::GetIsSlowMotionActive() ) 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]; 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); m_sQueueSample.m_nLoopsRemaining = CTimer::GetIsSlowMotionActive() ? (reflectionDistance * 800.f / 1029.f) : (reflectionDistance * 500.f / 1029.f);
if (m_sQueueSample.m_nLoopsRemaining > 3) { if (m_sQueueSample.m_nLoopsRemaining > 3) {
m_sQueueSample.m_fDistance = m_afReflectionsDistances[i]; m_sQueueSample.m_fDistance = m_afReflectionsDistances[i];
m_sQueueSample.m_nEmittingVolume = emittingVolume; SET_EMITTING_VOLUME(emittingVolume);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume > emittingVolume / 16) { if (m_sQueueSample.m_nVolume > emittingVolume / 16) {
m_sQueueSample.m_nCounter = oldCounter + (i + 1) * 256; m_sQueueSample.m_nCounter = oldCounter + (i + 1) * 256;
if (m_sQueueSample.m_nLoopCount) { if (m_sQueueSample.m_nLoopCount > 0) {
if ( CTimer::GetIsSlowMotionActive() ) { if ( CTimer::GetIsSlowMotionActive() ) {
m_sQueueSample.m_nFrequency = halfOldFreq + ((halfOldFreq * i) / ARRAY_SIZE(m_afReflectionsDistances)); m_sQueueSample.m_nFrequency = halfOldFreq + ((halfOldFreq * i) / ARRAY_SIZE(m_afReflectionsDistances));
} else { } else {
noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32); noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
if (noise <= 0) if (noise > 0)
m_sQueueSample.m_nFrequency += noise;
else
m_sQueueSample.m_nFrequency -= noise; m_sQueueSample.m_nFrequency -= noise;
else
m_sQueueSample.m_nFrequency += noise;
} }
} }
m_sQueueSample.m_nReleasingVolumeModificator += 20; m_sQueueSample.m_nReleasingVolumeModificator += 20;
@ -695,43 +767,87 @@ cAudioManager::AddReflectionsToRequestedQueue()
void void
cAudioManager::UpdateReflections() cAudioManager::UpdateReflections()
{ {
CVector camPos = TheCamera.GetPosition(); CVector camPos;
CColPoint colpoint; CColPoint colpoint;
CEntity *ent; CEntity *ent;
#if GTA_VERSION < GTAVC_PC_10
if (m_FrameCounter % 8 == 0) { 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] = camPos;
m_avecReflectionsPos[0].y += 100.f; m_avecReflectionsPos[0].y += 100.f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[0], colpoint, ent, true, false, false, true, false, true, true)) if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[0], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[0] = Distance(camPos, colpoint.point); m_afReflectionsDistances[0] = Distance(camPos, colpoint.point);
else else
m_afReflectionsDistances[0] = 100.0f; m_afReflectionsDistances[0] = 100.0f;
} else if ((m_FrameCounter + 1) % 8 == 0) { } else if ((m_FrameCounter + 1) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[1] = camPos; m_avecReflectionsPos[1] = camPos;
m_avecReflectionsPos[1].y -= 100.0f; m_avecReflectionsPos[1].y -= 100.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[1], colpoint, ent, true, false, false, true, false, true, true)) if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[1], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[1] = Distance(camPos, colpoint.point); m_afReflectionsDistances[1] = Distance(camPos, colpoint.point);
else else
m_afReflectionsDistances[1] = 100.0f; m_afReflectionsDistances[1] = 100.0f;
} else if ((m_FrameCounter + 2) % 8 == 0) { } else if ((m_FrameCounter + 2) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[2] = camPos; m_avecReflectionsPos[2] = camPos;
m_avecReflectionsPos[2].x -= 100.0f; m_avecReflectionsPos[2].x -= 100.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[2], colpoint, ent, true, false, false, true, false, true, true)) if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[2], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[2] = Distance(camPos, colpoint.point); m_afReflectionsDistances[2] = Distance(camPos, colpoint.point);
else else
m_afReflectionsDistances[2] = 100.0f; m_afReflectionsDistances[2] = 100.0f;
} else if ((m_FrameCounter + 3) % 8 == 0) { } else if ((m_FrameCounter + 3) % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[3] = camPos; m_avecReflectionsPos[3] = camPos;
m_avecReflectionsPos[3].x += 100.0f; m_avecReflectionsPos[3].x += 100.0f;
if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[3], colpoint, ent, true, false, false, true, false, true, true)) if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[3], colpoint, ent, true, false, false, true, false, true, true))
m_afReflectionsDistances[3] = Distance(camPos, colpoint.point); m_afReflectionsDistances[3] = Distance(camPos, colpoint.point);
else else
m_afReflectionsDistances[3] = 100.0f; m_afReflectionsDistances[3] = 100.0f;
} else if ((m_FrameCounter + 4) % 8 == 0) { } else if ((m_FrameCounter + 4) % 8 == 0) {
camPos = TheCamera.GetPosition();
camPos.y += 1.0f; camPos.y += 1.0f;
m_avecReflectionsPos[4] = camPos; m_avecReflectionsPos[4] = camPos;
m_avecReflectionsPos[4].z += 100.0f; m_avecReflectionsPos[4].z += 100.0f;
@ -739,8 +855,8 @@ cAudioManager::UpdateReflections()
m_afReflectionsDistances[4] = colpoint.point.z - camPos.z; m_afReflectionsDistances[4] = colpoint.point.z - camPos.z;
else else
m_afReflectionsDistances[4] = 100.0f; m_afReflectionsDistances[4] = 100.0f;
} else if ((m_FrameCounter + 5) % 8 == 0) { } else if ((m_FrameCounter + 5) % 8 == 0) {
camPos = TheCamera.GetPosition();
camPos.y -= 1.0f; camPos.y -= 1.0f;
m_avecReflectionsPos[5] = camPos; m_avecReflectionsPos[5] = camPos;
m_avecReflectionsPos[5].z += 100.0f; m_avecReflectionsPos[5].z += 100.0f;
@ -748,8 +864,8 @@ cAudioManager::UpdateReflections()
m_afReflectionsDistances[5] = colpoint.point.z - camPos.z; m_afReflectionsDistances[5] = colpoint.point.z - camPos.z;
else else
m_afReflectionsDistances[5] = 100.0f; m_afReflectionsDistances[5] = 100.0f;
} else if ((m_FrameCounter + 6) % 8 == 0) { } else if ((m_FrameCounter + 6) % 8 == 0) {
camPos = TheCamera.GetPosition();
camPos.x -= 1.0f; camPos.x -= 1.0f;
m_avecReflectionsPos[6] = camPos; m_avecReflectionsPos[6] = camPos;
m_avecReflectionsPos[6].z += 100.0f; m_avecReflectionsPos[6].z += 100.0f;
@ -757,8 +873,8 @@ cAudioManager::UpdateReflections()
m_afReflectionsDistances[6] = colpoint.point.z - camPos.z; m_afReflectionsDistances[6] = colpoint.point.z - camPos.z;
else else
m_afReflectionsDistances[6] = 100.0f; m_afReflectionsDistances[6] = 100.0f;
} else if ((m_FrameCounter + 7) % 8 == 0) { } else if ((m_FrameCounter + 7) % 8 == 0) {
camPos = TheCamera.GetPosition();
camPos.x += 1.0f; camPos.x += 1.0f;
m_avecReflectionsPos[7] = camPos; m_avecReflectionsPos[7] = camPos;
m_avecReflectionsPos[7].z += 100.0f; m_avecReflectionsPos[7].z += 100.0f;
@ -767,7 +883,9 @@ cAudioManager::UpdateReflections()
else else
m_afReflectionsDistances[7] = 100.0f; m_afReflectionsDistances[7] = 100.0f;
} }
#endif
} }
#endif // AUDIO_REFLECTIONS
void void
cAudioManager::AddReleasingSounds() cAudioManager::AddReleasingSounds()
@ -794,8 +912,11 @@ cAudioManager::AddReleasingSounds()
break; break;
} }
} }
if (!toProcess[i]) { if(!toProcess[i]) {
if (sample.m_nCounter <= 255 || !sample.m_nLoopsRemaining) { #ifdef AUDIO_REFLECTIONS
if(sample.m_nCounter <= 255 || sample.m_nLoopsRemaining == 0) // check if not reflection
#endif
{
if (sample.m_nReleasingVolumeDivider == 0) if (sample.m_nReleasingVolumeDivider == 0)
continue; continue;
if (sample.m_nLoopCount == 0) { if (sample.m_nLoopCount == 0) {
@ -829,40 +950,42 @@ cAudioManager::AddReleasingSounds()
void void
cAudioManager::ProcessActiveQueues() cAudioManager::ProcessActiveQueues()
{ {
CVector position;
uint32 freqDivided;
uint32 loopCount;
uint8 emittingVol;
uint8 vol;
uint8 offset;
float x;
bool8 flag; 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; bool8 missionState;
for (int32 i = 0; i < m_nActiveSamples; i++) { for (int32 i = 0; i < m_nActiveSamples; i++) {
m_asSamples[m_nActiveSampleQueue][i].m_bIsProcessed = FALSE; m_asSamples[m_nActiveSampleQueue][i].m_bIsProcessed = FALSE;
m_asActiveSamples[i].m_bIsProcessed = FALSE; m_asActiveSamples[i].m_bIsProcessed = FALSE;
} }
for (int32 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) { 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) { if (sample.m_nSampleIndex != NO_SAMPLE) {
for (int32 j = 0; j < m_nActiveSamples; j++) { for (int32 j = 0; j < m_nActiveSamples; j++) {
if (sample.m_nEntityIndex == m_asActiveSamples[j].m_nEntityIndex && if (sample.m_nEntityIndex == m_asActiveSamples[j].m_nEntityIndex && sample.m_nCounter == m_asActiveSamples[j].m_nCounter &&
sample.m_nCounter == m_asActiveSamples[j].m_nCounter &&
sample.m_nSampleIndex == m_asActiveSamples[j].m_nSampleIndex) { sample.m_nSampleIndex == m_asActiveSamples[j].m_nSampleIndex) {
if (sample.m_nLoopCount) { if (sample.m_nLoopCount) {
if (m_FrameCounter & 1)
if (m_FrameCounter & 1) { flag = !!(j & 1);
if (!(j & 1)) { else
flag = FALSE; flag = !(j & 1);
} else {
flag = TRUE;
}
} else if (j & 1) {
flag = FALSE;
} else {
flag = TRUE;
}
if (flag && !SampleManager.GetChannelUsedFlag(j)) { if (flag && !SampleManager.GetChannelUsedFlag(j)) {
sample.m_bLoopEnded = TRUE; sample.m_bLoopEnded = TRUE;
@ -871,7 +994,7 @@ cAudioManager::ProcessActiveQueues()
m_asActiveSamples[j].m_nEntityIndex = AEHANDLE_NONE; m_asActiveSamples[j].m_nEntityIndex = AEHANDLE_NONE;
continue; continue;
} }
if (!sample.m_nReleasingVolumeDivider) if (sample.m_nReleasingVolumeDivider == 0)
sample.m_nReleasingVolumeDivider = 1; sample.m_nReleasingVolumeDivider = 1;
} }
sample.m_bIsProcessed = TRUE; sample.m_bIsProcessed = TRUE;
@ -879,36 +1002,39 @@ cAudioManager::ProcessActiveQueues()
sample.m_nVolumeChange = -1; sample.m_nVolumeChange = -1;
if (!sample.m_bReleasingSoundFlag) { if (!sample.m_bReleasingSoundFlag) {
if (sample.m_bIs2D) { if (sample.m_bIs2D) {
if (field_4) { #ifdef EXTERNAL_3D_SOUND
emittingVol = 2 * Min(63, sample.m_nEmittingVolume); emittingVol = m_bDoubleVolume ? 2 * Min(63, sample.m_nEmittingVolume) : sample.m_nEmittingVolume;
} else { #else
emittingVol = sample.m_nEmittingVolume; emittingVol = m_bDoubleVolume ? 2 * Min(63, sample.m_nVolume) : sample.m_nVolume;
} #endif
SampleManager.SetChannelFrequency(j, sample.m_nFrequency); SampleManager.SetChannelFrequency(j, sample.m_nFrequency);
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannelEmittingVolume(j, emittingVol); SampleManager.SetChannelEmittingVolume(j, emittingVol);
#else
SampleManager.SetChannelPan(j, sample.m_nOffset);
SampleManager.SetChannelVolume(j, emittingVol);
#endif
} else { } else {
position2 = sample.m_fDistance;
position1 = m_asActiveSamples[j].m_fDistance;
m_asActiveSamples[j].m_fDistance = sample.m_fDistance; m_asActiveSamples[j].m_fDistance = sample.m_fDistance;
sample.m_nFrequency = ComputeDopplerEffectedFrequency( sample.m_nFrequency = ComputeDopplerEffectedFrequency(sample.m_nFrequency, position1, position2, sample.m_fSpeedMultiplier);
sample.m_nFrequency,
m_asActiveSamples[j].m_fDistance,
sample.m_fDistance,
sample.m_fSpeedMultiplier);
if (sample.m_nFrequency != m_asActiveSamples[j].m_nFrequency) { 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); uint32 freq = Clamp2((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency, 6000);
SampleManager.SetChannelFrequency(j, m_asActiveSamples[j].m_nFrequency); m_asActiveSamples[j].m_nFrequency = freq;
SampleManager.SetChannelFrequency(j, freq);
} }
#ifdef EXTERNAL_3D_SOUND
if (sample.m_nEmittingVolume != m_asActiveSamples[j].m_nEmittingVolume) { if (sample.m_nEmittingVolume != m_asActiveSamples[j].m_nEmittingVolume) {
vol = Clamp2((int8)sample.m_nEmittingVolume, (int8)m_asActiveSamples[j].m_nEmittingVolume, 10); vol = Clamp2((int8)sample.m_nEmittingVolume, (int8)m_asActiveSamples[j].m_nEmittingVolume, 10);
#else
if (field_4) { if (sample.m_nVolume != m_asActiveSamples[j].m_nVolume) {
emittingVol = 2 * Min(63, vol); vol = Clamp2((int8)sample.m_nVolume, (int8)m_asActiveSamples[j].m_nVolume, 10);
} else { #endif
emittingVol = vol; emittingVol = m_bDoubleVolume ? 2 * Min(63, vol) : vol;
}
missionState = FALSE; 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]) { if (m_sMissionAudio.m_bIsMobile[k]) {
missionState = TRUE; missionState = TRUE;
break; break;
@ -921,14 +1047,26 @@ cAudioManager::ProcessActiveQueues()
emittingVol = (emittingVol * field_5538) / 127; emittingVol = (emittingVol * field_5538) / 127;
} }
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannelEmittingVolume(j, emittingVol); SampleManager.SetChannelEmittingVolume(j, emittingVol);
m_asActiveSamples[j].m_nEmittingVolume = vol; m_asActiveSamples[j].m_nEmittingVolume = vol;
#else
SampleManager.SetChannelVolume(j, emittingVol);
m_asActiveSamples[j].m_nVolume = vol;
#endif
} }
TranslateEntity(&sample.m_vecPos, &position); TranslateEntity(&sample.m_vecPos, &position);
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannel3DPosition(j, position.x, position.y, position.z); 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); SampleManager.SetChannelReverbFlag(j, sample.m_bReverbFlag);
#endif
break; //continue for i break; //continue for i
} }
sample.m_bIsProcessed = FALSE; sample.m_bIsProcessed = FALSE;
@ -946,35 +1084,46 @@ cAudioManager::ProcessActiveQueues()
} }
} }
for (uint8 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) { for (uint8 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_bIsProcessed && !sample.m_bLoopEnded && if (!sample.m_bIsProcessed && !sample.m_bLoopEnded && m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed && sample.m_nSampleIndex < NO_SAMPLE) {
m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed && sample.m_nSampleIndex < NO_SAMPLE) { #ifdef AUDIO_REFLECTIONS
if (sample.m_nCounter > 255 && sample.m_nLoopCount && sample.m_nLoopsRemaining) { if (sample.m_nCounter > 255 && sample.m_nLoopCount > 0 && sample.m_nLoopsRemaining > 0) { // check if reflection
sample.m_nLoopsRemaining--; sample.m_nLoopsRemaining--;
sample.m_nReleasingVolumeDivider = 1; sample.m_nReleasingVolumeDivider = 1;
} else { } else
#endif
{
for (uint8 j = 0; j < m_nActiveSamples; j++) { for (uint8 j = 0; j < m_nActiveSamples; j++) {
uint8 k = (j + field_6) % m_nActiveSamples; uint8 k = (j + field_6) % m_nActiveSamples;
if (!m_asActiveSamples[k].m_bIsProcessed) { if (!m_asActiveSamples[k].m_bIsProcessed) {
if (sample.m_nLoopCount != 0) { if (sample.m_nLoopCount > 0) {
freqDivided = sample.m_nFrequency / m_nTimeSpent; samplesPerFrame = sample.m_nFrequency / m_nTimeSpent;
loopCount = sample.m_nLoopCount * SampleManager.GetSampleLength(sample.m_nSampleIndex); samplesToPlay = sample.m_nLoopCount * SampleManager.GetSampleLength(sample.m_nSampleIndex);
if (freqDivided == 0) if (samplesPerFrame == 0)
continue; continue;
sample.m_nReleasingVolumeDivider = loopCount / freqDivided + 1; sample.m_nReleasingVolumeDivider = samplesToPlay / samplesPerFrame + 1;
} }
memcpy(&m_asActiveSamples[k], &sample, sizeof(tSound)); 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); TranslateEntity(&m_asActiveSamples[k].m_vecPos, &position);
if (field_4) { #ifndef EXTERNAL_3D_SOUND
emittingVol = 2 * Min(63, m_asActiveSamples[k].m_nEmittingVolume); m_asActiveSamples[j].m_nOffset = ComputePan(m_asActiveSamples[j].m_fDistance, &position);
} else { #endif
emittingVol = m_asActiveSamples[k].m_nEmittingVolume;
} }
#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)) { if (SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex)) {
#endif
SampleManager.SetChannelFrequency(k, m_asActiveSamples[k].m_nFrequency); SampleManager.SetChannelFrequency(k, m_asActiveSamples[k].m_nFrequency);
bool8 isMobile = FALSE; 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]) { if (m_sMissionAudio.m_bIsMobile[l]) {
isMobile = TRUE; isMobile = TRUE;
break; break;
@ -987,24 +1136,40 @@ cAudioManager::ProcessActiveQueues()
} else { } else {
vol = (emittingVol * field_5538 / 127); vol = (emittingVol * field_5538 / 127);
} }
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannelEmittingVolume(k, vol); 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.SetChannelLoopPoints(k, m_asActiveSamples[k].m_nLoopStart, m_asActiveSamples[k].m_nLoopEnd);
SampleManager.SetChannelLoopCount(k, m_asActiveSamples[k].m_nLoopCount); SampleManager.SetChannelLoopCount(k, m_asActiveSamples[k].m_nLoopCount);
#endif
#if !defined(GTA_PS2) || defined(AUDIO_REVERB)
SampleManager.SetChannelReverbFlag(k, m_asActiveSamples[k].m_bReverbFlag); SampleManager.SetChannelReverbFlag(k, m_asActiveSamples[k].m_bReverbFlag);
#endif
#ifdef EXTERNAL_3D_SOUND
if (m_asActiveSamples[k].m_bIs2D) { if (m_asActiveSamples[k].m_bIs2D) {
offset = m_asActiveSamples[k].m_nOffset; uint8 offset = m_asActiveSamples[k].m_nOffset;
if (offset == 63) { if (offset == 63)
x = 0.0f; x = 0.0f;
} else if (offset >= 63) { else if (offset >= 63)
x = (offset - 63) * 1000.0f / 63; x = (offset - 63) * 1000.0f / 63;
} else { else
x = -(63 - offset) * 1000.0f / 63; //same like line below x = -(63 - offset) * 1000.0f / 63; //same like line below
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;
} }
position = CVector(x, 0.0f, 0.0f); SampleManager.SetChannel3DPosition(k, usedX, usedY, usedZ);
m_asActiveSamples[k].m_fSoundIntensity = 100000.0f; SampleManager.SetChannel3DDistances(k, m_asActiveSamples[k].m_SoundIntensity, 0.25f * m_asActiveSamples[k].m_SoundIntensity);
} #endif
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.StartChannel(k); SampleManager.StartChannel(k);
} }
m_asActiveSamples[k].m_bIsProcessed = TRUE; m_asActiveSamples[k].m_bIsProcessed = TRUE;
@ -1040,7 +1205,9 @@ cAudioManager::ClearActiveSamples()
m_asActiveSamples[i].m_nReleasingVolumeModificator = 5; m_asActiveSamples[i].m_nReleasingVolumeModificator = 5;
m_asActiveSamples[i].m_nFrequency = 0; m_asActiveSamples[i].m_nFrequency = 0;
m_asActiveSamples[i].m_nVolume = 0; m_asActiveSamples[i].m_nVolume = 0;
#ifdef EXTERNAL_3D_SOUND
m_asActiveSamples[i].m_nEmittingVolume = 0; m_asActiveSamples[i].m_nEmittingVolume = 0;
#endif
m_asActiveSamples[i].m_fDistance = 0.0f; m_asActiveSamples[i].m_fDistance = 0.0f;
m_asActiveSamples[i].m_bIsProcessed = FALSE; m_asActiveSamples[i].m_bIsProcessed = FALSE;
m_asActiveSamples[i].m_bLoopEnded = FALSE; m_asActiveSamples[i].m_bLoopEnded = FALSE;
@ -1050,19 +1217,30 @@ cAudioManager::ClearActiveSamples()
m_asActiveSamples[i].m_nLoopEnd = -1; m_asActiveSamples[i].m_nLoopEnd = -1;
#endif #endif
m_asActiveSamples[i].m_fSpeedMultiplier = 0.0f; 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_nOffset = 63;
m_asActiveSamples[i].m_bReleasingSoundFlag = FALSE; m_asActiveSamples[i].m_bReleasingSoundFlag = FALSE;
m_asActiveSamples[i].m_nCalculatedVolume = 0; m_asActiveSamples[i].m_nCalculatedVolume = 0;
m_asActiveSamples[i].m_nReleasingVolumeDivider = 0; m_asActiveSamples[i].m_nReleasingVolumeDivider = 0;
m_asActiveSamples[i].m_nVolumeChange = -1; m_asActiveSamples[i].m_nVolumeChange = -1;
m_asActiveSamples[i].m_vecPos = CVector(0.0f, 0.0f, 0.0f); m_asActiveSamples[i].m_vecPos = CVector(0.0f, 0.0f, 0.0f);
#ifdef AUDIO_REVERB
m_asActiveSamples[i].m_bReverbFlag = FALSE; m_asActiveSamples[i].m_bReverbFlag = FALSE;
#endif // AUDIO_REVERB
#ifdef AUDIO_REFLECTIONS
m_asActiveSamples[i].m_nLoopsRemaining = 0; m_asActiveSamples[i].m_nLoopsRemaining = 0;
m_asActiveSamples[i].m_bRequireReflection = FALSE; m_asActiveSamples[i].m_bRequireReflection = FALSE;
#endif // AUDIO_REFLECTIONS
} }
} }
void
cAudioManager::LoadBankIfNecessary(uint8 bank)
{
if(!SampleManager.IsSampleBankLoaded(bank))
SampleManager.LoadSampleBank(bank);
}
void void
cAudioManager::GenerateIntegerRandomNumberTable() cAudioManager::GenerateIntegerRandomNumberTable()
{ {
@ -1071,7 +1249,7 @@ cAudioManager::GenerateIntegerRandomNumberTable()
} }
} }
#ifdef GTA_PC #ifdef EXTERNAL_3D_SOUND
void void
cAudioManager::AdjustSamplesVolume() cAudioManager::AdjustSamplesVolume()
{ {
@ -1079,7 +1257,7 @@ cAudioManager::AdjustSamplesVolume()
tSound *pSample = &m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]]; tSound *pSample = &m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
if (!pSample->m_bIs2D) 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: public:
int32 m_nEntityIndex; int32 m_nEntityIndex;
int32 m_nCounter; uint32 m_nCounter;
int32 m_nSampleIndex; uint32 m_nSampleIndex;
uint8 m_nBankIndex; uint8 m_nBankIndex;
bool8 m_bIs2D; bool8 m_bIs2D;
int32 m_nReleasingVolumeModificator; uint32 m_nReleasingVolumeModificator;
uint32 m_nFrequency; uint32 m_nFrequency;
uint8 m_nVolume; uint8 m_nVolume;
float m_fDistance; float m_fDistance;
int32 m_nLoopCount; uint32 m_nLoopCount;
#ifndef GTA_PS2 #ifndef GTA_PS2
int32 m_nLoopStart; uint32 m_nLoopStart;
int32 m_nLoopEnd; int32 m_nLoopEnd;
#endif #endif
#ifdef EXTERNAL_3D_SOUND
uint8 m_nEmittingVolume; uint8 m_nEmittingVolume;
#endif
float m_fSpeedMultiplier; float m_fSpeedMultiplier;
float m_fSoundIntensity; float m_SoundIntensity;
bool8 m_bReleasingSoundFlag; bool8 m_bReleasingSoundFlag;
CVector m_vecPos; 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; bool8 m_bReverbFlag;
#endif
#ifdef AUDIO_REFLECTIONS
uint8 m_nLoopsRemaining; uint8 m_nLoopsRemaining;
bool8 m_bRequireReflection; // Used for oneshots bool8 m_bRequireReflection; // Used for oneshots
#endif
uint8 m_nOffset; uint8 m_nOffset;
uint8 field_4C; uint8 m_nFrontRearOffset;
int32 m_nReleasingVolumeDivider; uint32 m_nReleasingVolumeDivider;
bool8 m_bIsProcessed; bool8 m_bIsProcessed;
bool8 m_bLoopEnded; bool8 m_bLoopEnded;
int32 m_nCalculatedVolume; uint32 m_nCalculatedVolume;
int8 m_nVolumeChange; int8 m_nVolumeChange;
}; };
@ -51,7 +57,7 @@ public:
eAudioType m_nType; eAudioType m_nType;
void *m_pEntity; void *m_pEntity;
bool8 m_bIsUsed; bool8 m_bIsUsed;
uint8 m_bStatus; bool8 m_bStatus;
int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS]; int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS];
float m_afVolume[NUM_AUDIOENTITY_EVENTS]; float m_afVolume[NUM_AUDIOENTITY_EVENTS];
uint8 m_AudioEvents; uint8 m_AudioEvents;
@ -66,8 +72,11 @@ public:
int32 m_nEntityIndex; int32 m_nEntityIndex;
CVector m_vecPos; CVector m_vecPos;
float m_fDistance; float m_fDistance;
uint8 m_bVolume; uint8 m_nVolume;
int8 m_nProcess; int8 m_nProcess;
#if defined(EXTERNAL_3D_SOUND) && defined(FIX_BUGS)
uint8 m_nEmittingVolume;
#endif
}; };
VALIDATE_SIZE(tPedComment, 28); VALIDATE_SIZE(tPedComment, 28);
@ -113,7 +122,7 @@ class cMissionAudio
public: public:
CVector m_vecPos[MISSION_AUDIO_SLOTS]; CVector m_vecPos[MISSION_AUDIO_SLOTS];
bool8 m_bPredefinedProperties[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_nLoadingStatus[MISSION_AUDIO_SLOTS];
uint8 m_nPlayStatus[MISSION_AUDIO_SLOTS]; uint8 m_nPlayStatus[MISSION_AUDIO_SLOTS];
bool8 m_bIsPlaying[MISSION_AUDIO_SLOTS]; bool8 m_bIsPlaying[MISSION_AUDIO_SLOTS];
@ -163,7 +172,7 @@ public:
float m_fDistance; float m_fDistance;
CVehicle *m_pVehicle; CVehicle *m_pVehicle;
cTransmission *m_pTransmission; cTransmission *m_pTransmission;
int32 m_nIndex; uint32 m_nIndex;
float m_fVelocityChange; float m_fVelocityChange;
cVehicleParams() cVehicleParams()
@ -180,6 +189,24 @@ public:
VALIDATE_SIZE(cVehicleParams, 0x1C); 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 { enum {
REFLECTION_NORTH = 0, REFLECTION_NORTH = 0,
REFLECTION_SOUTH, REFLECTION_SOUTH,
@ -191,15 +218,19 @@ enum {
REFLECTION_CEIL_EAST, REFLECTION_CEIL_EAST,
MAX_REFLECTIONS, 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 class cAudioManager
{ {
public: public:
bool8 m_bIsInitialised; bool8 m_bIsInitialised;
uint8 m_bReverb; // unused bool8 m_bReverb; // unused
bool8 m_bFifthFrameFlag; bool8 m_bFifthFrameFlag;
uint8 m_nActiveSamples; uint8 m_nActiveSamples;
uint8 field_4; // unused bool8 m_bDoubleVolume; // unused
bool8 m_bDynamicAcousticModelingStatus; bool8 m_bDynamicAcousticModelingStatus;
int8 field_6; int8 field_6;
float m_fSpeedOfSound; float m_fSpeedOfSound;
@ -214,8 +245,10 @@ public:
tAudioEntity m_asAudioEntities[NUM_AUDIOENTITIES]; tAudioEntity m_asAudioEntities[NUM_AUDIOENTITIES];
int32 m_anAudioEntityIndices[NUM_AUDIOENTITIES]; int32 m_anAudioEntityIndices[NUM_AUDIOENTITIES];
int32 m_nAudioEntitiesTotal; int32 m_nAudioEntitiesTotal;
CVector m_avecReflectionsPos[NUM_AUDIO_REFLECTIONS]; #ifdef AUDIO_REFLECTIONS
float m_afReflectionsDistances[NUM_AUDIO_REFLECTIONS]; CVector m_avecReflectionsPos[MAX_REFLECTIONS];
float m_afReflectionsDistances[MAX_REFLECTIONS];
#endif
cAudioScriptObjectManager m_sAudioScriptObjectManager; cAudioScriptObjectManager m_sAudioScriptObjectManager;
// miami // miami
@ -243,307 +276,318 @@ public:
uint8 field_5538; // something related to phone dialogues uint8 field_5538; // something related to phone dialogues
int32 m_anRandomTable[5]; int32 m_anRandomTable[5];
uint8 m_nTimeSpent; uint8 m_nTimeSpent;
uint8 m_nUserPause; bool8 m_nUserPause;
uint8 m_nPreviousUserPause; bool8 m_nPreviousUserPause;
uint32 m_FrameCounter; uint32 m_FrameCounter;
cAudioManager(); cAudioManager();
~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 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 Terminate();
void TranslateEntity(Const CVector *v1, CVector *v2) const; void Service();
int32 CreateEntity(eAudioType type, void *entity);
void UpdateGasPedalAudio(CVehicle *veh, int vehType); void DestroyEntity(int32 id); // inlined in vc
void UpdateReflections(); bool8 GetEntityStatus(int32 id);
bool8 UsesReverseWarning(int32 model) const; void SetEntityStatus(int32 id, bool8 status);
bool8 UsesSiren(cVehicleParams &params) const; void *GetEntityPointer(int32 id);
bool8 UsesSirenSwitching(cVehicleParams &params) const; void PlayOneShot(int32 index, uint16 sound, float vol);
void SetEffectsMasterVolume(uint8 volume);
CVehicle *FindVehicleOfPlayer(); void SetMusicMasterVolume(uint8 volume);
void SetPedTalkingStatus(CPed *ped, bool8 status); void SetMP3BoostVolume(uint8 volume);
void SetPlayersMood(uint8 mood, uint32 time); void SetEffectsFadeVol(uint8 volume);
void SetMusicFadeVol(uint8 volume);
float Sqrt(float v) const { return v <= 0.0f ? 0.0f : ::Sqrt(v); } void SetOutputMode(bool8 surround);
void ResetTimers(uint32 time);
void DestroyAllGameCreatedEntities();
#ifdef GTA_PC #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 void AdjustSamplesVolume(); // inlined
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // inlined uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // inlined
#endif #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 RESET_LOOP_OFFSETS
#define SET_LOOP_OFFSETS(sample) #define SET_LOOP_OFFSETS(sample)
#endif #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) #if defined(AUDIO_MSS) && !defined(PS2_AUDIO_CHANNELS)
static_assert(sizeof(cAudioManager) == 0x5558, "cAudioManager: error"); static_assert(sizeof(cAudioManager) == 0x5558, "cAudioManager: error");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -584,8 +584,18 @@ void CCarAI::TellOccupantsToLeaveCar(CVehicle* pVehicle)
{ {
if (pVehicle->pDriver){ if (pVehicle->pDriver){
pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_CAR, pVehicle); 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); pVehicle->pDriver->Say(SOUND_PED_LEAVE_VEHICLE);
break;
}
} }
int timer = 100; int timer = 100;
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++){ for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++){
@ -601,8 +611,18 @@ void CCarAI::TellOccupantsToFleeCar(CVehicle* pVehicle)
{ {
if (pVehicle->pDriver && !pVehicle->pDriver->IsPlayer()) { if (pVehicle->pDriver && !pVehicle->pDriver->IsPlayer()) {
pVehicle->pDriver->SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE); 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); pVehicle->pDriver->Say(SOUND_PED_LEAVE_VEHICLE);
break;
}
} }
int timer = 100; int timer = 100;
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) { for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) {

View File

@ -94,7 +94,7 @@ int32 CCarCtrl::NumRandomCars;
int32 CCarCtrl::NumParkedCars; int32 CCarCtrl::NumParkedCars;
int32 CCarCtrl::NumPermanentCars; int32 CCarCtrl::NumPermanentCars;
int8 CCarCtrl::CountDownToCarsAtStart; int8 CCarCtrl::CountDownToCarsAtStart;
int32 CCarCtrl::MaxNumberOfCarsInUse = 12; int32 CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS;
uint32 CCarCtrl::LastTimeLawEnforcerCreated; uint32 CCarCtrl::LastTimeLawEnforcerCreated;
uint32 CCarCtrl::LastTimeFireTruckCreated; uint32 CCarCtrl::LastTimeFireTruckCreated;
uint32 CCarCtrl::LastTimeAmbulanceCreated; uint32 CCarCtrl::LastTimeAmbulanceCreated;
@ -400,7 +400,7 @@ CCarCtrl::GenerateOneRandomCar()
pVehicle->m_bSirenOrAlarm = true; pVehicle->m_bSirenOrAlarm = true;
pVehicle->AutoPilot.m_nNextPathNodeInfo = connectionId; pVehicle->AutoPilot.m_nNextPathNodeInfo = connectionId;
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane = CGeneral::GetRandomNumber() % lanesOnCurrentRoad; 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 carLength = 1.0f + (boundingBox->max.y - boundingBox->min.y) / 2;
float distanceBetweenNodes = (pCurNode->GetPosition() - pNextNode->GetPosition()).Magnitude2D(); 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. */ /* 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 distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D();
float threshold = OFFSCREEN_DESPAWN_RANGE; float threshold = OFFSCREEN_DESPAWN_RANGE;
#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE
if (pVehicle->GetIsOnScreen() || if (pVehicle->GetIsOnScreen() ||
TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingLeft ||
TheCamera.Cams[TheCamera.ActiveCam].LookingRight || TheCamera.Cams[TheCamera.ActiveCam].LookingRight ||
@ -975,11 +976,15 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
pVehicle->bIsLawEnforcer || pVehicle->bIsLawEnforcer ||
pVehicle->bIsCarParkVehicle || pVehicle->bIsCarParkVehicle ||
CTimer::GetTimeInMilliseconds() < pVehicle->m_nSetPieceExtendedRangeTime CTimer::GetTimeInMilliseconds() < pVehicle->m_nSetPieceExtendedRangeTime
){ )
#endif
{
threshold = ONSCREEN_DESPAWN_RANGE * TheCamera.GenerationDistMultiplier; threshold = ONSCREEN_DESPAWN_RANGE * TheCamera.GenerationDistMultiplier;
} }
#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE
if (TheCamera.GetForward().z < -0.9f) if (TheCamera.GetForward().z < -0.9f)
threshold = 70.0f; threshold = 70.0f;
#endif
if (pVehicle->bExtendedRange) if (pVehicle->bExtendedRange)
threshold *= EXTENDED_RANGE_DESPAWN_MULTIPLIER; threshold *= EXTENDED_RANGE_DESPAWN_MULTIPLIER;
if (distanceToPlayer > threshold && !CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){ if (distanceToPlayer > threshold && !CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){
@ -1554,7 +1559,7 @@ void CCarCtrl::WeaveThroughCarsSectorList(CPtrList& lst, CVehicle* pVehicle, CPh
continue; continue;
if (Abs(pTestVehicle->GetPosition().z - pVehicle->GetPosition().z) >= VEHICLE_HEIGHT_DIFF_TO_CONSIDER_WEAVING) if (Abs(pTestVehicle->GetPosition().z - pVehicle->GetPosition().z) >= VEHICLE_HEIGHT_DIFF_TO_CONSIDER_WEAVING)
continue; continue;
if (pTestVehicle != pVehicle) if (pTestVehicle != pVehicle && (!pVehicle->bPartOfConvoy || !pTestVehicle->bPartOfConvoy))
WeaveForOtherCar(pTestVehicle, pVehicle, pAngleToWeaveLeft, pAngleToWeaveRight); 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) void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float* pAngleToWeaveLeft, float* pAngleToWeaveRight)
{ {
CVehicle* pOtherCar = (CVehicle*)pOtherEntity; CVehicle* pOtherCar = (CVehicle*)pOtherEntity;
if (pVehicle->bPartOfConvoy && pOtherCar->bPartOfConvoy)
return;
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE && pOtherEntity == FindPlayerVehicle()) if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE && pOtherEntity == FindPlayerVehicle())
return; return;
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMCAR_CLOSE && pOtherEntity == pVehicle->AutoPilot.m_pTargetCar) 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); float actualFactor = CalcSpeedScaleFactor(pPos1, pPos2, pDir1->x, pDir1->y, pDir2->x, pDir2->y);
CVector2D dir1 = *pDir1 * actualFactor; CVector2D dir1 = *pDir1 * actualFactor;
CVector2D dir2 = *pDir2 * actualFactor; CVector2D dir2 = *pDir2 * actualFactor;
float t1 = Abs(DotProduct2D(*pPos1 - *pPos2, *pDir1)); float t1 = Abs(DotProduct2D(*pPos2 - *pPos1, *pDir1));
float t2 = Abs(DotProduct2D(*pPos2 - *pPos1, *pDir2)); float t2 = Abs(DotProduct2D(*pPos1 - *pPos2, *pDir2));
float curveCoef; float curveCoef;
if (t1 > t2) { 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; curveCoef = 0.0f;
else 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 { 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; curveCoef = 1.0f;
else else
curveCoef = 0.5f - 0.5f * Cos(3.1415f * between * (t1 + t2) / (2 * t1)); curveCoef = 0.5f - 0.5f * Cos(3.1415f * between * (t1 + t2) / (2 * t1));

View File

@ -102,6 +102,15 @@ CGameLogic::Update()
CVector vecRestartPos; CVector vecRestartPos;
float fRestartFloat; 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; if (CCutsceneMgr::IsCutsceneProcessing()) return;
UpdateShortCut(); UpdateShortCut();

View File

@ -1986,7 +1986,7 @@ void CGarages::GivePlayerDetonator()
float CGarages::FindDoorHeightForMI(int32 mi) 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() void CGarage::TidyUpGarage()

View File

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

View File

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

View File

@ -60,7 +60,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
CEntity* pEntityToAttack = (CEntity*)FindPlayerVehicle(); CEntity* pEntityToAttack = (CEntity*)FindPlayerVehicle();
if (!pEntityToAttack) if (!pEntityToAttack)
pEntityToAttack = (CEntity*)FindPlayerPed(); pEntityToAttack = (CEntity*)FindPlayerPed();
CColModel* pPoliceColModel = CModelInfo::GetModelInfo(MI_POLICE)->GetColModel(); CColModel* pPoliceColModel = CModelInfo::GetColModel(MI_POLICE);
float fRadius = pVehicle->GetBoundRadius() / pPoliceColModel->boundingSphere.radius; float fRadius = pVehicle->GetBoundRadius() / pPoliceColModel->boundingSphere.radius;
for (int32 i = 0; i < 2; i++) { for (int32 i = 0; i < 2; i++) {
const int32 roadBlockIndex = i + 2 * roadBlockType; const int32 roadBlockIndex = i + 2 * roadBlockType;
@ -217,7 +217,7 @@ CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2)
vehicleId = MI_ENFORCER; vehicleId = MI_ENFORCER;
if (!CStreaming::HasModelLoaded(vehicleId)) if (!CStreaming::HasModelLoaded(vehicleId))
vehicleId = MI_POLICE; vehicleId = MI_POLICE;
CColModel* pVehicleColModel = CModelInfo::GetModelInfo(vehicleId)->GetColModel(); CColModel *pVehicleColModel = CModelInfo::GetColModel(vehicleId);
float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f; float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f;
int16 numRoadblockVehicles = Min(6, (int16)(distBetween / fModelRadius)); int16 numRoadblockVehicles = Min(6, (int16)(distBetween / fModelRadius));
for (int16 i = 0; i < numRoadblockVehicles; i++) { 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.RotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + 3.1416f);
tmp.SetTranslateOnly(offset * forward + pos); tmp.SetTranslateOnly(offset * forward + pos);
tmp.GetPosition().z += 0.6f; 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; int16 colliding = 0;
CWorld::FindObjectsKindaColliding(tmp.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false); CWorld::FindObjectsKindaColliding(tmp.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false);
if (!colliding) { 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 #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
int CollectParameterForDebug(char* buf, bool& var); int CollectParameterForDebug(char* buf, bool& var);
void GetStoredParameterForDebug(char* buf); void GetStoredParameterForDebug(char* buf);
void LogOnStartProcessing();
void LogBeforeProcessingCommand(int32 command);
void LogAfterProcessingCommand(int32 command);
static char commandInfo[];
static uint32 storedIp;
#endif #endif
float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; } float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; }
@ -575,13 +582,26 @@ public:
static void SetObjectiveForAllPedsInCollective(int, eObjective); static void SetObjectiveForAllPedsInCollective(int, eObjective);
#endif #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 #ifdef USE_DEBUG_SCRIPT_LOADER
extern int scriptToLoad; static int ScriptToLoad;
static int OpenScript();
#endif #endif
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
static void LogAfterScriptInitializing();
static void LogBeforeScriptProcessing();
static void LogAfterScriptProcessing();
#endif
};
#ifdef MISSION_REPLAY #ifdef MISSION_REPLAY
static_assert(false, "Mission replay is not supported");
extern int AllowMissionReplay; extern int AllowMissionReplay;
extern uint32 WaitForMissionActivate; extern uint32 WaitForMissionActivate;
extern uint32 WaitForSave; extern uint32 WaitForSave;
@ -592,10 +612,28 @@ extern bool gbTryingPorn4Again;
extern int IsInAmmunation; extern int IsInAmmunation;
extern int MissionSkipLevel; extern int MissionSkipLevel;
uint32 AddExtraDeathDelay(); #ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
void RetryMission(int, int); extern bool UsingMobileScript;
extern bool AlreadySavedGame;
#endif #endif
#ifdef USE_DEBUG_SCRIPT_LOADER uint32 AddExtraDeathDelay();
extern int scriptToLoad; 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 #endif

View File

@ -149,6 +149,11 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
} }
case COMMAND_ADD_EXPLOSION: case COMMAND_ADD_EXPLOSION:
CollectParameters(&m_nIp, 4); CollectParameters(&m_nIp, 4);
#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); CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true);
return 0; return 0;

View File

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

View File

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

View File

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

View File

@ -293,7 +293,11 @@ enum {
COMMAND_IS_PLAYER_IN_ZONE, COMMAND_IS_PLAYER_IN_ZONE,
COMMAND_IS_PLAYER_PRESSING_HORN, COMMAND_IS_PLAYER_PRESSING_HORN,
COMMAND_HAS_CHAR_SPOTTED_PLAYER, COMMAND_HAS_CHAR_SPOTTED_PLAYER,
#ifdef SUPPORT_GINPUT_SCRIPT
COMMAND_HAS_PAD_IN_HANDS,
#else
COMMAND_ORDER_CHAR_TO_BACKDOOR, COMMAND_ORDER_CHAR_TO_BACKDOOR,
#endif
COMMAND_ADD_CHAR_TO_GANG, COMMAND_ADD_CHAR_TO_GANG,
COMMAND_IS_CHAR_OBJECTIVE_PASSED, COMMAND_IS_CHAR_OBJECTIVE_PASSED,
COMMAND_SET_CHAR_DRIVE_AGGRESSION, 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); 12.0f, 1.0f, 40.0f, false, 0.0f);
if (id >= 0) { if (id >= 0) {
if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f) if (DotProduct(TheCamera.GetForward(), ent->GetForward()) > 0.0f)
CCoronas::RegisterCorona((uintptr)ent + id, CCoronas::RegisterCorona((uintptr)ent + id,
r * CTimeCycle::GetSpriteBrightness() * 0.7f, r * CTimeCycle::GetSpriteBrightness() * 0.7f,
g * CTimeCycle::GetSpriteBrightness() * 0.7f, g * CTimeCycle::GetSpriteBrightness() * 0.7f,

View File

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

View File

@ -2708,6 +2708,14 @@ const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
#undef PS2_CROSS #undef PS2_CROSS
#undef PS2_SQUARE #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 UP
#undef DOWN #undef DOWN
#undef LEFT #undef LEFT
@ -2733,6 +2741,9 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *
case CMenuManager::CONTROLLER_DUALSHOCK4: case CMenuManager::CONTROLLER_DUALSHOCK4:
Buttons = CFont::ButtonsSlot != -1 ? PlayStationButtons : PlayStationButtons_noIcons; Buttons = CFont::ButtonsSlot != -1 ? PlayStationButtons : PlayStationButtons_noIcons;
break; break;
case CMenuManager::CONTROLLER_NINTENDO_SWITCH:
Buttons = CFont::ButtonsSlot != -1 ? NintendoSwitchButtons : NintendoSwitchButtons_noIcons;
break;
default: default:
#endif #endif
Buttons = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons; Buttons = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons;
@ -2748,6 +2759,9 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *
case CMenuManager::CONTROLLER_DUALSHOCK4: case CMenuManager::CONTROLLER_DUALSHOCK4:
Buttons = PlayStationButtons_noIcons; Buttons = PlayStationButtons_noIcons;
break; break;
case CMenuManager::CONTROLLER_NINTENDO_SWITCH:
Buttons = NintendoSwitchButtons_noIcons;
break;
default: default:
Buttons = XboxButtons_noIcons; Buttons = XboxButtons_noIcons;
break; break;

View File

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

View File

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

View File

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

View File

@ -333,6 +333,7 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.Initialise(); DMAudio.Initialise();
#ifndef GTA_PS2 #ifndef GTA_PS2
#ifdef EXTERNAL_3D_SOUND
if ( DMAudio.GetNum3DProvidersAvailable() == 0 ) if ( DMAudio.GetNum3DProvidersAvailable() == 0 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER; FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER;
@ -344,6 +345,7 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
DMAudio.SetSpeakerConfig(FrontEndMenuManager.m_PrefsSpeakers); DMAudio.SetSpeakerConfig(FrontEndMenuManager.m_PrefsSpeakers);
#endif
DMAudio.SetDynamicAcousticModelingStatus(FrontEndMenuManager.m_PrefsDMA); DMAudio.SetDynamicAcousticModelingStatus(FrontEndMenuManager.m_PrefsDMA);
DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume); DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume);
DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume); DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume);
@ -373,6 +375,10 @@ bool CGame::Initialise(const char* datFile)
CPools::Initialise(); CPools::Initialise();
#ifndef GTA_PS2 #ifndef GTA_PS2
#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(); CIniFile::LoadIniFile();
#endif #endif
#ifdef USE_TEXTURE_POOL #ifdef USE_TEXTURE_POOL
@ -899,7 +905,13 @@ void CGame::Process(void)
CEventList::Update(); CEventList::Update();
CParticle::Update(); CParticle::Update();
gFireManager.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) { if (processTime >= 2) {
#endif
CPopulation::Update(false); CPopulation::Update(false);
} else { } else {
uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();

View File

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

View File

@ -1,5 +1,9 @@
#pragma once #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 class CIniFile
{ {
public: public:

View File

@ -30,11 +30,17 @@ CMenuScreen aScreens[] = {
MENUACTION_MUSICVOLUME, "FEA_MUS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 40, 76, MENUALIGN_LEFT, 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_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, 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_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, 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_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, 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, 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, MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER,
}, },
@ -329,6 +335,16 @@ CMenuScreen aScreens[] = {
}, },
#endif #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 // MENUPAGE_OUTRO - Originally 34
{ "", 0, 0, }, { "", 0, 0, },
}; };

View File

@ -27,6 +27,9 @@
#include "Pad.h" #include "Pad.h"
#include "ControllerConfig.h" #include "ControllerConfig.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "IniFile.h"
#include "CarCtrl.h"
#include "Population.h"
// Menu screens array is at the bottom of the file. // Menu screens array is at the bottom of the file.
@ -34,7 +37,7 @@
#ifdef CUSTOM_FRONTEND_OPTIONS #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, #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 #else
#define VIDEOMODE_SELECTOR #define VIDEOMODE_SELECTOR
@ -64,6 +67,15 @@
#define DUALPASS_SELECTOR #define DUALPASS_SELECTOR
#endif #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 #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, #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 #else
@ -136,6 +148,9 @@ void RestoreDefDisplay(int8 action) {
#ifdef FREE_CAM #ifdef FREE_CAM
TheCamera.bFreeCam = false; TheCamera.bFreeCam = false;
#endif #endif
#ifdef PED_CAR_DENSITY_SLIDERS
CIniFile::LoadIniFile();
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
FrontEndMenuManager.m_PrefsBrightness = 256; FrontEndMenuManager.m_PrefsBrightness = 256;
FrontEndMenuManager.m_PrefsLOD = 1.2f; FrontEndMenuManager.m_PrefsLOD = 1.2f;
@ -182,6 +197,17 @@ void IslandLoadingAfterChange(int8 before, int8 after) {
} }
#endif #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 #ifndef MULTISAMPLING
void GraphicsGoBack() { void GraphicsGoBack() {
} }
@ -354,7 +380,7 @@ void DetectJoystickGoBack() {
#endif #endif
#ifdef GAMEPAD_MENU #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) void ControllerTypeAfterChange(int8 before, int8 after)
{ {
FrontEndMenuManager.LoadController(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_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_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, 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_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, 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_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, 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, 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, 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, { "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_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, MENUACTION_DRAWDIST, "FEM_LOD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
DENSITY_SLIDERS
#ifdef LEGACY_MENU_OPTIONS #ifdef LEGACY_MENU_OPTIONS
MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#endif #endif
@ -426,6 +459,7 @@ CMenuScreenCustom aScreens[] = {
{ "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil, { "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_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, MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
DENSITY_SLIDERS
CUTSCENE_BORDERS_TOGGLE CUTSCENE_BORDERS_TOGGLE
FREE_CAM_TOGGLE FREE_CAM_TOGGLE
MENUACTION_LEGENDS, "MAP_LEG", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, MENUACTION_LEGENDS, "MAP_LEG", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
@ -604,7 +638,11 @@ CMenuScreenCustom aScreens[] = {
// MENUPAGE_OPTIONS = 27 // MENUPAGE_OPTIONS = 27
{ "FET_OPT", MENUPAGE_NONE, nil, nil, { "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, 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_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, MENUACTION_CHANGEMENU, "FEO_DIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#ifdef GRAPHICS_MENU_OPTIONS #ifdef GRAPHICS_MENU_OPTIONS
@ -660,7 +698,11 @@ CMenuScreenCustom aScreens[] = {
{ "", 0, nil, nil, }, { "", 0, nil, nil, },
#ifdef GAMEPAD_MENU #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, { "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_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, MENUACTION_CTRLDISPLAY, "FEC_CDP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, 0, 0, MENUALIGN_LEFT,
INVERT_PAD_SELECTOR INVERT_PAD_SELECTOR
@ -726,7 +768,9 @@ CMenuScreenCustom aScreens[] = {
// MENUPAGE_GRAPHICS_SETTINGS // MENUPAGE_GRAPHICS_SETTINGS
{ "FET_GFX", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true, true}), GraphicsGoBack, { "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, 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, MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
VIDEOMODE_SELECTOR VIDEOMODE_SELECTOR
#ifdef LEGACY_MENU_OPTIONS #ifdef LEGACY_MENU_OPTIONS
@ -756,6 +800,17 @@ CMenuScreenCustom aScreens[] = {
}, },
#endif #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 // MENUPAGE_OUTRO = 34
{ "", 0, nil, nil, }, { "", 0, nil, nil, },
}; };

View File

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

View File

@ -16,6 +16,7 @@
#include "Script.h" #include "Script.h"
#include "TxdStore.h" #include "TxdStore.h"
#include "World.h" #include "World.h"
#include "SaveBuf.h"
#include "Streaming.h" #include "Streaming.h"
#include "SpecialFX.h" #include "SpecialFX.h"
#include "Font.h" #include "Font.h"
@ -65,6 +66,9 @@ CSprite2d CRadar::RadioVCPRSprite;
CSprite2d CRadar::RadioEspantosoSprite; CSprite2d CRadar::RadioEspantosoSprite;
CSprite2d CRadar::RadioEmotionSprite; CSprite2d CRadar::RadioEmotionSprite;
CSprite2d CRadar::RadioWaveSprite; CSprite2d CRadar::RadioWaveSprite;
#ifdef MAP_ENHANCEMENTS
CSprite2d CRadar::WaypointSprite;
#endif
CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = { CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = {
nil, nil,
@ -106,7 +110,10 @@ CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = {
&RadioVCPRSprite, &RadioVCPRSprite,
&RadioEspantosoSprite, &RadioEspantosoSprite,
&RadioEmotionSprite, &RadioEmotionSprite,
&RadioWaveSprite &RadioWaveSprite,
#ifdef MAP_ENHANCEMENTS
&WaypointSprite,
#endif
}; };
// Why this doesn't coincide with world coordinates i don't know // 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); 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) { if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition(); 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); 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; break;
@ -502,7 +509,7 @@ void CRadar::Draw3dMarkers()
CEntity *entity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[i].m_nEntityHandle); 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) { if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition(); 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); 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; break;
@ -818,6 +825,9 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha) 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)); 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) { if (FrontEndMenuManager.m_bMenuMapActive) {
@ -935,6 +945,9 @@ const char* gRadarTexNames[] = {
void void
CRadar::Initialise() CRadar::Initialise()
{ {
#ifdef MAP_ENHANCEMENTS
TargetMarkerId = -1;
#endif
for (int i = 0; i < NUMRADARBLIPS; i++) { for (int i = 0; i < NUMRADARBLIPS; i++) {
ms_RadarTrace[i].m_BlipIndex = 1; ms_RadarTrace[i].m_BlipIndex = 1;
SetRadarMarkerState(i, false); SetRadarMarkerState(i, false);
@ -1002,9 +1015,11 @@ INITSAVEBUF
WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE); WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE);
#ifdef MAP_ENHANCEMENTS #ifdef MAP_ENHANCEMENTS
bool bWaypointDeleted = false;
if (TargetMarkerId != -1) { if (TargetMarkerId != -1) {
ClearBlip(TargetMarkerId); ClearBlip(TargetMarkerId);
TargetMarkerId = -1; TargetMarkerId = -1;
bWaypointDeleted = true;
} }
#endif #endif
@ -1029,6 +1044,11 @@ INITSAVEBUF
SkipSaveBuf(buf, sizeof(sRadarTraceSave)); SkipSaveBuf(buf, sizeof(sRadarTraceSave));
} }
#ifdef MAP_ENHANCEMENTS
if(bWaypointDeleted)
ToggleTargetMarker(TargetMarkerPos.x, TargetMarkerPos.y);
#endif
VALIDATESAVEBUF(*size); VALIDATESAVEBUF(*size);
} }
@ -1076,6 +1096,43 @@ CRadar::LoadTextures()
RadioEspantosoSprite.SetTexture("REspantoso"); RadioEspantosoSprite.SetTexture("REspantoso");
RadioEmotionSprite.SetTexture("REmotion"); RadioEmotionSprite.SetTexture("REmotion");
RadioWaveSprite.SetTexture("RWave"); 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(); CTxdStore::PopCurrentTxd();
} }
@ -1270,6 +1327,9 @@ void CRadar::Shutdown()
RadioEspantosoSprite.Delete(); RadioEspantosoSprite.Delete();
RadioEmotionSprite.Delete(); RadioEmotionSprite.Delete();
RadioWaveSprite.Delete(); RadioWaveSprite.Delete();
#ifdef MAP_ENHANCEMENTS
WaypointSprite.Delete();
#endif
RemoveRadarSections(); RemoveRadarSections();
} }
@ -1431,12 +1491,12 @@ CRadar::ToggleTargetMarker(float x, float y)
{ {
if (TargetMarkerId == -1) { if (TargetMarkerId == -1) {
int nextBlip; int nextBlip;
for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) { for (nextBlip = NUMRADARBLIPS-1; nextBlip >= 0; nextBlip--) {
if (!ms_RadarTrace[nextBlip].m_bInUse) if (!ms_RadarTrace[nextBlip].m_bInUse)
break; break;
} }
if (nextBlip == NUMRADARBLIPS) if (nextBlip == 0)
return; return;
ms_RadarTrace[nextBlip].m_eBlipType = BLIP_COORD; 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_bDim = 0;
ms_RadarTrace[nextBlip].m_bInUse = 1; ms_RadarTrace[nextBlip].m_bInUse = 1;
ms_RadarTrace[nextBlip].m_Radius = 1.0f; 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; TargetMarkerPos = pos;
ms_RadarTrace[nextBlip].m_vec2DPos = pos; ms_RadarTrace[nextBlip].m_vec2DPos = pos;
ms_RadarTrace[nextBlip].m_vecPos = pos; ms_RadarTrace[nextBlip].m_vecPos = pos;
ms_RadarTrace[nextBlip].m_nEntityHandle = 0; ms_RadarTrace[nextBlip].m_nEntityHandle = 0;
ms_RadarTrace[nextBlip].m_wScale = 5; ms_RadarTrace[nextBlip].m_wScale = 5;
ms_RadarTrace[nextBlip].m_eBlipDisplay = BLIP_DISPLAY_BLIP_ONLY; 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); TargetMarkerId = CRadar::GetNewUniqueBlipIndex(nextBlip);
} else { } else {
ClearBlip(TargetMarkerId); ClearBlip(TargetMarkerId);
@ -1739,6 +1799,11 @@ CRadar::DrawLegend(int32 x, int32 y, int32 sprite)
case RADAR_SPRITE_RADIO_WAVE: case RADAR_SPRITE_RADIO_WAVE:
text = TheText.Get("LG_34"); text = TheText.Get("LG_34");
break; break;
#ifdef MAP_ENHANCEMENTS
case RADAR_SPRITE_WAYPOINT:
text = TheText.Get("LG_38");
break;
#endif
default: default:
break; break;
} }

View File

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

View File

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

View File

@ -11,6 +11,11 @@
#define __STDC_LIMIT_MACROS // so we get UINT32_MAX etc #define __STDC_LIMIT_MACROS // so we get UINT32_MAX etc
#endif #endif
#ifdef __SWITCH__
#include <switch.h>
#endif
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <math.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 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; } inline float sq(float x) { return x*x; }
#define SQR(x) ((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) #define _TODOCONST(x) (x)
#ifdef CHECK_STRUCT_SIZES #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 #else
#define VALIDATE_SIZE(struc, size) #define VALIDATE_SIZE(struc, size)
#endif #endif

View File

@ -135,7 +135,6 @@ enum Config {
NUM_SOUNDS_SAMPLES_BANKS = 2, NUM_SOUNDS_SAMPLES_BANKS = 2,
NUM_AUDIOENTITIES = 250, NUM_AUDIOENTITIES = 250,
NUM_AUDIO_REFLECTIONS = 8,
NUM_SCRIPT_MAX_ENTITIES = 40, NUM_SCRIPT_MAX_ENTITIES = 40,
NUM_GARAGE_STORED_CARS = 4, NUM_GARAGE_STORED_CARS = 4,
@ -165,6 +164,11 @@ enum Config {
#define GTA_VERSION GTAVC_PC_11 #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: // TODO(MIAMI): someone ought to find and check out uses of these defines:
//#define GTA3_STEAM_PATCH //#define GTA3_STEAM_PATCH
//#define GTAVC_JP_PATCH //#define GTAVC_JP_PATCH
@ -176,12 +180,19 @@ enum Config {
# define VU_COLLISION # define VU_COLLISION
# define PS2_MENU # define PS2_MENU
#elif defined GTA_PC #elif defined GTA_PC
# define EXTERNAL_3D_SOUND
# define AUDIO_REVERB
# ifndef GTA_HANDHELD
# define PC_PLAYER_CONTROLS // mouse player/cam mode # define PC_PLAYER_CONTROLS // mouse player/cam mode
# endif
# define GTA_REPLAY # define GTA_REPLAY
# define GTA_SCENE_EDIT # define GTA_SCENE_EDIT
# define PC_MENU # define PC_MENU
# define PC_WATER # define PC_WATER
#elif defined GTA_XBOX #elif defined GTA_XBOX
#elif defined GTA_MOBILE
# define MISSION_REPLAY
# define SIMPLER_MISSIONS
#endif #endif
// This is enabled for all released games. // This is enabled for all released games.
@ -217,6 +228,7 @@ enum Config {
#define DONT_FIX_REPLAY_BUGS #define DONT_FIX_REPLAY_BUGS
#define USE_TXD_CDIMAGE // generate and load textures from txd.img #define USE_TXD_CDIMAGE // generate and load textures from txd.img
//#define USE_TEXTURE_POOL // not possible because R* used custom RW33 //#define USE_TEXTURE_POOL // not possible because R* used custom RW33
#define AUDIO_REFLECTIONS
#else #else
// This enables things from the PS2 version on PC // This enables things from the PS2 version on PC
#define GTA_PS2_STUFF #define GTA_PS2_STUFF
@ -274,6 +286,9 @@ enum Config {
#define NO_MOVIES // add option to disable intro videos #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) #if defined(__LP64__) || defined(_WIN64)
#define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build #define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build
#endif #endif
@ -327,7 +342,7 @@ enum Config {
#if !defined(RW_GL3) && defined(_WIN32) #if !defined(RW_GL3) && defined(_WIN32)
#define XINPUT #define XINPUT
#endif #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. #define DETECT_JOYSTICK_MENU // Then we'll expect user to enter Controller->Detect joysticks if his joystick isn't detected at the start.
#endif #endif
#define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m #define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m
@ -349,7 +364,7 @@ enum Config {
//# define PS2_MENU_USEALLPAGEICONS //# define PS2_MENU_USEALLPAGEICONS
#else #else
# define MAP_ENHANCEMENTS // Adding waypoint and better mouse support # define MAP_ENHANCEMENTS // Adding waypoint and better mouse support
# ifdef XINPUT # if defined(XINPUT) || defined(GTA_HANDHELD)
# define GAMEPAD_MENU // Add gamepad menu # define GAMEPAD_MENU // Add gamepad menu
# endif # endif
//# define TRIANGLE_BACK_BUTTON //# define TRIANGLE_BACK_BUTTON
@ -367,6 +382,7 @@ enum Config {
# define MULTISAMPLING // adds MSAA option # define MULTISAMPLING // adds MSAA option
#endif #endif
# define INVERT_LOOK_FOR_PAD // enable the hidden option # define INVERT_LOOK_FOR_PAD // enable the hidden option
# define PED_CAR_DENSITY_SLIDERS
# endif # endif
#endif #endif
@ -376,14 +392,16 @@ enum Config {
#define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely #define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely
#define SUPPORT_JAPANESE_SCRIPT #define SUPPORT_JAPANESE_SCRIPT
//#define SUPPORT_XBOX_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) #if (defined SUPPORT_XBOX_SCRIPT && defined SUPPORT_MOBILE_SCRIPT)
static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually exclusive"); static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually exclusive");
#endif #endif
#ifdef PC_MENU #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 #endif
//#define SIMPLIER_MISSIONS // apply simplifications from mobile
//#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT //#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log #define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log
@ -400,6 +418,10 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT #undef USE_BASIC_SCRIPT_DEBUG_OUTPUT
#endif #endif
#ifndef MISSION_REPLAY
#undef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
#endif
// Replay // Replay
//#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool! //#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!) //#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 #define FREE_CAM // Rotating cam
// Audio // 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 RADIO_SCROLL_TO_PREV_STATION // Won't work without FIX_BUGS
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot #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) #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 PS2_ALPHA_TEST
#undef NO_ISLAND_LOADING #undef NO_ISLAND_LOADING
#undef PS2_AUDIO_CHANNELS #undef PS2_AUDIO_CHANNELS
#undef EXTENDED_OFFSCREEN_DESPAWN_RANGE
#endif #endif
#ifdef __WIIU__ #ifdef __WIIU__
@ -469,4 +496,19 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#undef USE_CUTSCENE_SHADOW_FOR_PED #undef USE_CUTSCENE_SHADOW_FOR_PED
#endif #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 #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 "Camera.h"
#include "MBlur.h" #include "MBlur.h"
#include "ControllerConfig.h" #include "ControllerConfig.h"
#include "CarCtrl.h"
#include "Population.h"
#include "IniFile.h"
#if 1
#include "crossplatform.h" #include "crossplatform.h"
#endif
#ifndef _WIN32 #ifndef _WIN32
#include "assert.h" #include "assert.h"
@ -132,7 +133,7 @@ void LangJapSelect(int8 action)
void void
CustomFrontendOptionsPopulate(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; int fd;
// These work only if we have neo folder, so they're dynamically added // 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", "MusicVolume", &FrontEndMenuManager.m_PrefsMusicVolume);
ReadIniIfExists("Audio", "MP3BoostVolume", &FrontEndMenuManager.m_PrefsMP3BoostVolume); ReadIniIfExists("Audio", "MP3BoostVolume", &FrontEndMenuManager.m_PrefsMP3BoostVolume);
ReadIniIfExists("Audio", "Radio", &FrontEndMenuManager.m_PrefsRadioStation); ReadIniIfExists("Audio", "Radio", &FrontEndMenuManager.m_PrefsRadioStation);
#ifdef EXTERNAL_3D_SOUND
ReadIniIfExists("Audio", "SpeakerType", &FrontEndMenuManager.m_PrefsSpeakers); ReadIniIfExists("Audio", "SpeakerType", &FrontEndMenuManager.m_PrefsSpeakers);
ReadIniIfExists("Audio", "Provider", &FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); ReadIniIfExists("Audio", "Provider", &FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
#endif
ReadIniIfExists("Audio", "DynamicAcoustics", &FrontEndMenuManager.m_PrefsDMA); ReadIniIfExists("Audio", "DynamicAcoustics", &FrontEndMenuManager.m_PrefsDMA);
ReadIniIfExists("Display", "Brightness", &FrontEndMenuManager.m_PrefsBrightness); ReadIniIfExists("Display", "Brightness", &FrontEndMenuManager.m_PrefsBrightness);
ReadIniIfExists("Display", "DrawDistance", &FrontEndMenuManager.m_PrefsLOD); ReadIniIfExists("Display", "DrawDistance", &FrontEndMenuManager.m_PrefsLOD);
@ -570,22 +573,30 @@ bool LoadINISettings()
// CFO check // CFO check
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
// CFO only supports saving uint8 right now
// Migrate from old .ini to new .ini // 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); 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 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) { 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 #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; return true;
} }
@ -609,8 +620,10 @@ void SaveINISettings()
StoreIni("Audio", "MusicVolume", FrontEndMenuManager.m_PrefsMusicVolume); StoreIni("Audio", "MusicVolume", FrontEndMenuManager.m_PrefsMusicVolume);
StoreIni("Audio", "MP3BoostVolume", FrontEndMenuManager.m_PrefsMP3BoostVolume); StoreIni("Audio", "MP3BoostVolume", FrontEndMenuManager.m_PrefsMP3BoostVolume);
StoreIni("Audio", "Radio", FrontEndMenuManager.m_PrefsRadioStation); StoreIni("Audio", "Radio", FrontEndMenuManager.m_PrefsRadioStation);
#ifdef EXTERNAL_3D_SOUND
StoreIni("Audio", "SpeakerType", FrontEndMenuManager.m_PrefsSpeakers); StoreIni("Audio", "SpeakerType", FrontEndMenuManager.m_PrefsSpeakers);
StoreIni("Audio", "Provider", FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); StoreIni("Audio", "Provider", FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
#endif
StoreIni("Audio", "DynamicAcoustics", FrontEndMenuManager.m_PrefsDMA); StoreIni("Audio", "DynamicAcoustics", FrontEndMenuManager.m_PrefsDMA);
StoreIni("Display", "Brightness", FrontEndMenuManager.m_PrefsBrightness); StoreIni("Display", "Brightness", FrontEndMenuManager.m_PrefsBrightness);
StoreIni("Display", "DrawDistance", FrontEndMenuManager.m_PrefsLOD); StoreIni("Display", "DrawDistance", FrontEndMenuManager.m_PrefsLOD);
@ -666,8 +679,10 @@ void SaveINISettings()
break; break;
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
// Beware: CFO only supports saving uint8 right now if (option.m_Action == MENUACTION_CFO_SLIDER)
StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *option.m_CFO->value); 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); OutputDebugString(buff);
} }
#endif
#ifndef MASTER
void re3_usererror(const char *format, ...) void re3_usererror(const char *format, ...)
{ {
va_list va; va_list va;

View File

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

View File

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

View File

@ -35,6 +35,8 @@ typedef void (*ReturnPrevPageFunc)();
typedef void (*ChangeFunc)(int8 before, int8 after); // called after updating the value. 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 // 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 // for dynamic options
typedef wchar* (*DrawFunc)(bool* disabled, bool userHovering); // you must return a pointer for right text. 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. // you can also set *disabled if you want to gray it out.

View File

@ -741,7 +741,7 @@ uint32 im2D_UV2_Vao;
void void
openim2d_uv2(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); glGenBuffers(1, &im2D_UV2_Ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 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); setAttribPointers(im2d_UV2_attribDesc, 4);
#endif #endif
glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform); setUniform(u_xform, xform);
flushCache(); flushCache();
glDrawElements(primTypeMap[primType], numIndices, glDrawElements(primTypeMap[primType], numIndices,

View File

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

View File

@ -104,6 +104,14 @@ enum RwRasterFormat
rwRASTERFORMATMASK = 0xff00 rwRASTERFORMATMASK = 0xff00
}; };
enum RwRasterLockMode
{
rwRASTERLOCKWRITE = rw::Raster::LOCKWRITE,
rwRASTERLOCKREAD = rw::Raster::LOCKREAD,
rwRASTERLOCKNOFETCH = rw::Raster::LOCKNOFETCH,
rwRASTERLOCKRAW = rw::Raster::LOCKRAW,
};
enum RwRasterFlipMode enum RwRasterFlipMode
{ {
rwRASTERFLIPDONTWAIT = 0, 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 "2dEffect.h"
#include "SimpleModelInfo.h" #include "SimpleModelInfo.h"
#include "MloModelInfo.h"
#include "TimeModelInfo.h" #include "TimeModelInfo.h"
#include "WeaponModelInfo.h" #include "WeaponModelInfo.h"
#include "ClumpModelInfo.h" #include "ClumpModelInfo.h"

View File

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

View File

@ -345,13 +345,19 @@ CPed::SetAttack(CEntity *victim)
if (m_pLookTarget) { if (m_pLookTarget) {
SetAimFlag(m_pLookTarget); SetAimFlag(m_pLookTarget);
} else if (this == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam()) { #ifdef FREE_CAM
} else if (this != FindPlayerPed() || !((CPlayerPed*)this)->m_bFreeAimActive) {
#else
} else {
#endif
if (this == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
SetAimFlag(m_fRotationCur); SetAimFlag(m_fRotationCur);
((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch(); ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
} else if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) { } else if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) {
SetAimFlag(m_fRotationCur); SetAimFlag(m_fRotationCur);
} }
} }
}
#ifdef FIX_BUGS #ifdef FIX_BUGS
// fix aiming for flamethrower and minigun while using PC controls // fix aiming for flamethrower and minigun while using PC controls
else if (curWeapon->m_AnimToPlay == ASSOCGRP_FLAMETHROWER && TheCamera.Cams[0].Using3rdPersonMouseCam() && this == FindPlayerPed()) else if (curWeapon->m_AnimToPlay == ASSOCGRP_FLAMETHROWER && TheCamera.Cams[0].Using3rdPersonMouseCam() && this == FindPlayerPed())
@ -821,6 +827,9 @@ CPed::Attack(void)
if (!bIsDucking && !GetFireAnimNotDucking(ourWeapon) && ourWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) if (!bIsDucking && !GetFireAnimNotDucking(ourWeapon) && ourWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM; m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
else else
#ifdef FREE_CAM
if (!IsPlayer() || !((CPlayerPed*)this)->m_bFreeAimActive)
#endif
m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
} }
@ -1017,6 +1026,15 @@ CPed::Attack(void)
weaponAnimAssoc->SetCurrentTime(animLoopEnd); weaponAnimAssoc->SetCurrentTime(animLoopEnd);
weaponAnimAssoc->flags &= ~ASSOC_RUNNING; weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
SetPointGunAt(m_pPointGunAt); 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 { } else {
ClearAimFlag(); ClearAimFlag();

View File

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

View File

@ -98,6 +98,9 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_nAttackDirToCheck = 0; m_nAttackDirToCheck = 0;
m_nLastBusFareCollected = 0; m_nLastBusFareCollected = 0;
idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles"); idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles");
#ifdef FREE_CAM
m_bFreeAimActive = false;
#endif
} }
void void
@ -574,8 +577,12 @@ CPlayerPed::DoWeaponSmoothSpray(void)
return -1.0f; return -1.0f;
case WEAPONTYPE_CHAINSAW: 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; return PI / 128.0f;
}
else if (GetFireAnimGround(weaponInfo, false) && RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(weaponInfo, false))) else if (GetFireAnimGround(weaponInfo, false) && RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(weaponInfo, false)))
return PI / 176.f; return PI / 176.f;
else else
@ -1221,11 +1228,21 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
} }
if (padUsed->DuckJustDown() && !bIsDucking && m_nMoveState != PEDMOVE_SPRINT) { 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; bCrouchWhenShooting = true;
SetDuck(60000, true); SetDuck(60000, true);
} else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT || } else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT ||
padUsed->GetSprint() || padUsed->JumpJustDown() || padUsed->ExitVehicleJustDown())) { padUsed->GetSprint() || padUsed->JumpJustDown() || padUsed->ExitVehicleJustDown())) {
#ifdef FIX_BUGS
// same fix as above except for standing up
if(!m_pPointGunAt)
ClearPointGunAt();
#endif
ClearDuck(true); ClearDuck(true);
bCrouchWhenShooting = false; bCrouchWhenShooting = false;
} }
@ -1328,17 +1345,22 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
if ((padUsed->GetTarget() && CAN_AIM_WITH_ARM) || padUsed->GetWeapon()) { if ((padUsed->GetTarget() && CAN_AIM_WITH_ARM) || padUsed->GetWeapon()) {
float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation); 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. // On this one we can rotate arm.
if (CAN_AIM_WITH_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; pointedGun = 2;
SetLookFlag(limitedCam, true); m_bFreeAimActive = true;
SetLookFlag(limitedCam, true, true);
SetAimFlag(limitedCam); 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 { } else {
m_fRotationDest = limitedCam; m_fRotationDest = limitedCam;
changedHeadingRate = 2; changedHeadingRate = 2;
@ -1366,10 +1388,20 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
changedHeadingRate = 0; changedHeadingRate = 0;
RestoreHeadingRate(); RestoreHeadingRate();
} }
if (pointedGun == 1 && m_nPedState != PED_ATTACK) { 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; pointedGun = 0;
ClearPointGunAt(); ClearPointGunAt();
} }
}
#endif #endif
if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT && !TheCamera.Using1stPersonWeaponMode() && weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM)) { if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT && !TheCamera.Using1stPersonWeaponMode() && weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM)) {
@ -1465,6 +1497,13 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
padMoveInGameUnit = CVector2D(leftRight, upDown).Magnitude() / PAD_MOVE_TO_GAME_WORLD_MOVE; 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) { if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) {
float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown); float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation); float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);

View File

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

View File

@ -40,8 +40,8 @@ bool CPopulation::ms_bGivePedsWeapons;
int32 CPopulation::m_AllRandomPedsThisType = -1; int32 CPopulation::m_AllRandomPedsThisType = -1;
float CPopulation::PedDensityMultiplier = 1.0f; float CPopulation::PedDensityMultiplier = 1.0f;
uint32 CPopulation::ms_nTotalMissionPeds; uint32 CPopulation::ms_nTotalMissionPeds;
int32 CPopulation::MaxNumberOfPedsInUse = 25; int32 CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS;
int32 CPopulation::MaxNumberOfPedsInUseInterior = 40; int32 CPopulation::MaxNumberOfPedsInUseInterior = DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR;
uint32 CPopulation::ms_nNumCivMale; uint32 CPopulation::ms_nNumCivMale;
uint32 CPopulation::ms_nNumCivFemale; uint32 CPopulation::ms_nNumCivFemale;
uint32 CPopulation::ms_nNumCop; uint32 CPopulation::ms_nNumCop;
@ -1095,6 +1095,7 @@ CPopulation::ManagePopulation(void)
} }
float dist = (ped->GetPosition() - playerPos).Magnitude2D(); float dist = (ped->GetPosition() - playerPos).Magnitude2D();
bool pedIsFarAway = false; bool pedIsFarAway = false;
if (ped->IsGangMember()) if (ped->IsGangMember())
@ -1105,8 +1106,9 @@ CPopulation::ManagePopulation(void)
if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist || if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist ||
(!ped->bCullExtraFarAway && PedCreationDistMultiplier() * PED_REMOVE_DIST * TheCamera.GenerationDistMultiplier < dist)) { (!ped->bCullExtraFarAway && PedCreationDistMultiplier() * PED_REMOVE_DIST * TheCamera.GenerationDistMultiplier < dist)) {
pedIsFarAway = true; 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 (CTimer::GetTimeInMilliseconds() > ped->m_nExtendedRangeTimer && !ped->GetIsOnScreen()) {
if (TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER if (TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER
&& TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER_RUNABOUT && 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; 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); int gangModel = ChooseGangOccupation(pedType - PEDTYPE_GANG1);
if (((CPedModelInfo*)CModelInfo::GetModelInfo(gangModel))->GetRwObject()) { if (((CPedModelInfo*)CModelInfo::GetModelInfo(gangModel))->GetRwObject()) {
CEntity* obstacles[6] = { nil, nil, nil, nil, nil, nil }; 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; bool foundObstacle = false;
for (int m = 0; m < ARRAY_SIZE(obstacles); m++) { for (int m = 0; m < ARRAY_SIZE(obstacles); m++) {
CEntity* obstacle = obstacles[m]; CEntity* obstacle = obstacles[m];
@ -1626,7 +1630,7 @@ CPopulation::PlaceCouple(ePedType manType, int32 manModel, ePedType womanType, i
return; return;
if (!TheCamera.IsSphereVisible(coors, 1.5f) || MIN_CREATION_DIST * PedCreationDistMultiplier() <= (coors - FindPlayerPed()->GetPosition()).Magnitude2D()) { 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; bool manFoundGround;
float manGroundZ = CWorld::FindGroundZFor3DCoord(coors.x, coors.y, coors.z, &manFoundGround) + 1.0f; float manGroundZ = CWorld::FindGroundZFor3DCoord(coors.x, coors.y, coors.z, &manFoundGround) + 1.0f;
if (manFoundGround) { if (manFoundGround) {
@ -1660,7 +1664,7 @@ CPopulation::PlaceCouple(ePedType manType, int32 manModel, ePedType womanType, i
CEntity* obstacles[3]; CEntity* obstacles[3];
memcpy(obstacles, gCoupleObstacles, sizeof(gCoupleObstacles)); 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++) { for (int i = 0; i < ARRAY_SIZE(obstacles); i++) {
CEntity *obstacle = obstacles[i]; CEntity *obstacle = obstacles[i];
if (obstacle) { if (obstacle) {
@ -1736,7 +1740,7 @@ CPopulation::PlaceMallPedsAsStationaryGroup(CVector const& coors, int32 group)
if (pedModelInfo->GetRwObject()) { if (pedModelInfo->GetRwObject()) {
CEntity* obstacles[6] = { nil, nil, nil, nil, nil, nil }; 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; bool foundObstacle = false;
for (int m = 0; m < ARRAY_SIZE(obstacles); m++) { for (int m = 0; m < ARRAY_SIZE(obstacles); m++) {
CEntity* obstacle = 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_pos2 = pos2;
m_pos3 = pos3; 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_pos0.z -= escalatorStepHeight;
m_pos1.z -= escalatorStepHeight; m_pos1.z -= escalatorStepHeight;
m_pos2.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; CFontDetails CFont::Details;
int16 CFont::NewLine; bool16 CFont::NewLine;
CSprite2d CFont::Sprite[MAX_FONTS]; CSprite2d CFont::Sprite[MAX_FONTS];
CFontRenderState CFont::RenderState; CFontRenderState CFont::RenderState;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -84,6 +84,7 @@ public:
// All actually unused // All actually unused
static bool DefaultVisibilityCB(RpClump *clump); static bool DefaultVisibilityCB(RpClump *clump);
static bool FrustumSphereCB(RpClump *clump); static bool FrustumSphereCB(RpClump *clump);
static bool MloVisibilityCB(RpClump *clump);
static bool VehicleVisibilityCB(RpClump *clump); static bool VehicleVisibilityCB(RpClump *clump);
static bool VehicleVisibilityCB_BigVehicle(RpClump *clump); static bool VehicleVisibilityCB_BigVehicle(RpClump *clump);
@ -104,6 +105,7 @@ public:
static CSimpleModelInfo *GetAtomicModelInfo(RpAtomic *atomic); static CSimpleModelInfo *GetAtomicModelInfo(RpAtomic *atomic);
static void SetAtomicFlag(RpAtomic*, int); static void SetAtomicFlag(RpAtomic*, int);
static void ClearAtomicFlag(RpAtomic*, int); static void ClearAtomicFlag(RpAtomic*, int);
static void SetAtomicId(RpAtomic *atomic, int);
static int GetAtomicId(RpAtomic *atomic); static int GetAtomicId(RpAtomic *atomic);
static void SetAtomicRenderCallback(RpAtomic*, RpAtomicCallBackRender); static void SetAtomicRenderCallback(RpAtomic*, RpAtomicCallBackRender);
@ -133,8 +135,10 @@ public:
int alpha; int alpha;
}; };
static void SetClumpModelInfo(RpClump*, CClumpModelInfo*); static void SetClumpModelInfo(RpClump*, CClumpModelInfo*);
static CClumpModelInfo *GetClumpModelInfo(RpClump*);
static void SetClumpAlpha(RpClump*, int); static void SetClumpAlpha(RpClump*, int);
static int GetClumpAlpha(RpClump*); static int GetClumpAlpha(RpClump*);
static bool IsClumpVisible(RpClump*);
static void *ClumpConstructor(void *object, int32 offset, int32 len); static void *ClumpConstructor(void *object, int32 offset, int32 len);
static void *ClumpDestructor(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); CGame::TidyUpMemory(true, false);
StillToFadeOut = true; StillToFadeOut = true;
JustLoadedDontFadeInYet = true; JustLoadedDontFadeInYet = true;
TheCamera.Fade(0.0f, 0); TheCamera.Fade(0.0f, FADE_OUT);
CTheScripts::Process(); CTheScripts::Process();
} }
@ -693,6 +693,7 @@ enum
SAVE_TYPE_64_BIT = 2, SAVE_TYPE_64_BIT = 2,
SAVE_TYPE_MSVC = 4, SAVE_TYPE_MSVC = 4,
SAVE_TYPE_GCC = 8, SAVE_TYPE_GCC = 8,
SAVE_TYPE_STEAM = 16,
}; };
uint8 uint8
@ -707,6 +708,14 @@ GetSaveType(char *savename)
uint8 *buf = work_buff; uint8 *buf = work_buff;
CFileMgr::Read(file, (const char *)work_buff, size); // simple vars + scripts 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); // ped pool
LoadSaveDataBlockNoCheck(buf, file, size); // garages LoadSaveDataBlockNoCheck(buf, file, size); // garages
@ -757,6 +766,29 @@ GetSaveType(char *savename)
return save_type; 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 static void
FixGarages(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size) 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 bool
FixSave(int32 slot, uint8 save_type) 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; return true;
bool success = false; bool success = false;
@ -1044,17 +1076,29 @@ FixSave(int32 slot, uint8 save_type)
totalSize = 0; totalSize = 0;
CFileMgr::Read(file_in, (const char *)&size, sizeof(size)); CFileMgr::Read(file_in, (const char *)&size, sizeof(size));
size = align4bytes(size);
buf = work_buff; buf = work_buff;
CFileMgr::Read(file_in, (const char *)work_buff, size); // simple vars + scripts CFileMgr::Read(file_in, (const char *)work_buff, size); // simple vars + scripts
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); WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // ped pool LoadSaveDataBlockNoCheck(buf, file_in, size); // ped pool
WriteSavaDataBlockNoFunc(buf, file_out, size); WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // garages 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 LoadSaveDataBlockNoCheck(buf, file_in, size); // game logic
WriteSavaDataBlockNoFunc(buf, file_out, size); WriteSavaDataBlockNoFunc(buf, file_out, size);
@ -1176,13 +1220,20 @@ void DisplaySaveResult(int unk, char* name)
bool SaveGameForPause(int type) 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; return false;
}
if (type != SAVE_TYPE_QUICKSAVE_FOR_MISSION_REPLAY && WaitForSave > CTimer::GetTimeInMilliseconds()) {
debug("SaveGameForPause failed WaitForSave");
return false;
}
WaitForSave = 0; 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); DisplaySaveResult(3, CStats::LastMissionPassedName);
return false; return false;
} }
debug("SaveGameForPause ******************************** %s doSave %d", CStats::LastMissionPassedName, !CTheScripts::bAlreadyRunningAMissionScript);
IsQuickSave = type; IsQuickSave = type;
MissionStartTime = 0; MissionStartTime = 0;
int res = PcSaveHelper.SaveSlot(PAUSE_SAVE_SLOT); int res = PcSaveHelper.SaveSlot(PAUSE_SAVE_SLOT);

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