diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 68704fad..00000000 --- a/.pylintrc +++ /dev/null @@ -1,635 +0,0 @@ -[MAIN] - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Clear in-memory caches upon conclusion of linting. Useful if running pylint -# in a server-like mode. -clear-cache-post-run=no - -# Load and enable all available extensions. Use --list-extensions to see a list -# all available extensions. -#enable-all-extensions= - -# In error mode, messages with a category besides ERROR or FATAL are -# suppressed, and no reports are done by default. Error mode is compatible with -# disabling specific errors. -#errors-only= - -# Always return a 0 (non-error) status code, even if lint errors are found. -# This is primarily useful in continuous integration scripts. -#exit-zero= - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -extension-pkg-allow-list= - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. (This is an alternative name to extension-pkg-allow-list -# for backward compatibility.) -extension-pkg-whitelist= - -# Return non-zero exit code if any of these messages/categories are detected, -# even if score is above --fail-under value. Syntax same as enable. Messages -# specified are enabled, while categories only check already-enabled messages. -fail-on= - -# Specify a score threshold under which the program will exit with error. -fail-under=10 - -# Interpret the stdin as a python script, whose filename needs to be passed as -# the module_or_package argument. -#from-stdin= - -# Files or directories to be skipped. They should be base names, not paths. -ignore=CVS - -# Add files or directories matching the regular expressions patterns to the -# ignore-list. The regex matches against paths and can be in Posix or Windows -# format. Because '\\' represents the directory delimiter on Windows systems, -# it can't be used as an escape character. -ignore-paths= - -# Files or directories matching the regular expression patterns are skipped. -# The regex matches against base names, not paths. The default value ignores -# Emacs file locks -ignore-patterns=^\.# - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis). It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use, and will cap the count on Windows to -# avoid hangs. -jobs=1 - -# Control the amount of potential inferred values when inferring a single -# object. This can help the performance when dealing with large functions or -# complex, nested conditions. -limit-inference-results=100 - -# List of plugins (as comma separated values of python module names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. -persistent=yes - -# Minimum Python version to use for version dependent checks. Will default to -# the version used to run pylint. -py-version=3.12 - -# Discover python modules and packages in the file system subtree. -recursive=no - -# Add paths to the list of the source roots. Supports globbing patterns. The -# source root is an absolute path or a path relative to the current working -# directory used to determine a package namespace for modules located under the -# source root. -source-roots= - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - -# In verbose mode, extra non-checker-related info will be displayed. -#verbose= - - -[BASIC] - -# Naming style matching correct argument names. -argument-naming-style=snake_case - -# Regular expression matching correct argument names. Overrides argument- -# naming-style. If left empty, argument names will be checked with the set -# naming style. -#argument-rgx= - -# Naming style matching correct attribute names. -attr-naming-style=snake_case - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. If left empty, attribute names will be checked with the set naming -# style. -#attr-rgx= - -# Bad variable names which should always be refused, separated by a comma. -bad-names=foo, - bar, - baz, - toto, - tutu, - tata - -# Bad variable names regexes, separated by a comma. If names match any regex, -# they will always be refused -bad-names-rgxs= - -# Naming style matching correct class attribute names. -class-attribute-naming-style=any - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. If left empty, class attribute names will be checked -# with the set naming style. -#class-attribute-rgx= - -# Naming style matching correct class constant names. -class-const-naming-style=UPPER_CASE - -# Regular expression matching correct class constant names. Overrides class- -# const-naming-style. If left empty, class constant names will be checked with -# the set naming style. -#class-const-rgx= - -# Naming style matching correct class names. -class-naming-style=PascalCase - -# Regular expression matching correct class names. Overrides class-naming- -# style. If left empty, class names will be checked with the set naming style. -#class-rgx= - -# Naming style matching correct constant names. -const-naming-style=UPPER_CASE - -# Regular expression matching correct constant names. Overrides const-naming- -# style. If left empty, constant names will be checked with the set naming -# style. -#const-rgx= - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Naming style matching correct function names. -function-naming-style=snake_case - -# Regular expression matching correct function names. Overrides function- -# naming-style. If left empty, function names will be checked with the set -# naming style. -#function-rgx= - -# Good variable names which should always be accepted, separated by a comma. -good-names=i, - j, - k, - ex, - Run, - _ - -# Good variable names regexes, separated by a comma. If names match any regex, -# they will always be accepted -good-names-rgxs= - -# Include a hint for the correct naming format with invalid-name. -include-naming-hint=no - -# Naming style matching correct inline iteration names. -inlinevar-naming-style=any - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. If left empty, inline iteration names will be checked -# with the set naming style. -#inlinevar-rgx= - -# Naming style matching correct method names. -method-naming-style=snake_case - -# Regular expression matching correct method names. Overrides method-naming- -# style. If left empty, method names will be checked with the set naming style. -#method-rgx= - -# Naming style matching correct module names. -module-naming-style=snake_case - -# Regular expression matching correct module names. Overrides module-naming- -# style. If left empty, module names will be checked with the set naming style. -#module-rgx= - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -# These decorators are taken in consideration only for invalid-name. -property-classes=abc.abstractproperty - -# Regular expression matching correct type alias names. If left empty, type -# alias names will be checked with the set naming style. -#typealias-rgx= - -# Regular expression matching correct type variable names. If left empty, type -# variable names will be checked with the set naming style. -#typevar-rgx= - -# Naming style matching correct variable names. -variable-naming-style=snake_case - -# Regular expression matching correct variable names. Overrides variable- -# naming-style. If left empty, variable names will be checked with the set -# naming style. -#variable-rgx= - - -[CLASSES] - -# Warn about protected attribute access inside special methods -check-protected-access-in-special-methods=no - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp, - asyncSetUp, - __post_init__ - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - - -[DESIGN] - -# List of regular expressions of class ancestor names to ignore when counting -# public methods (see R0903) -exclude-too-few-public-methods= - -# List of qualified class names to ignore when counting class parents (see -# R0901) -ignored-parents= - -# Maximum number of arguments for function / method. -max-args=6 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Maximum number of boolean expressions in an if statement (see R0916). -max-bool-expr=5 - -# Maximum number of branch for function / method body. -max-branches=30 - -# Maximum number of locals for function / method body. -max-locals=30 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body. -max-returns=6 - -# Maximum number of statements in function / method body. -max-statements=75 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=0 - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when caught. -overgeneral-exceptions=builtins.BaseException,builtins.Exception - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=2 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=200 - -# Maximum number of lines in a module. -max-module-lines=1000 - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[IMPORTS] - -# List of modules that can be imported at any level, not just the top level -# one. -allow-any-import-level= - -# Allow explicit reexports by alias from a package __init__. -allow-reexport-from-package=no - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules= - -# Output a graph (.gv or any supported image format) of external dependencies -# to the given file (report RP0402 must not be disabled). -ext-import-graph= - -# Output a graph (.gv or any supported image format) of all (i.e. internal and -# external) dependencies to the given file (report RP0402 must not be -# disabled). -import-graph= - -# Output a graph (.gv or any supported image format) of internal dependencies -# to the given file (report RP0402 must not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - -# Couples of modules and preferred modules, separated by a comma. -preferred-modules= - - -[LOGGING] - -# The type of string formatting that logging methods do. `old` means using % -# formatting, `new` is for `{}` formatting. -logging-format-style=old - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules=logging - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, -# UNDEFINED. -confidence=HIGH, - CONTROL_FLOW, - INFERENCE, - INFERENCE_FAILURE, - UNDEFINED - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then re-enable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable=raw-checker-failed, - bad-inline-option, - locally-disabled, - file-ignored, - suppressed-message, - useless-suppression, - deprecated-pragma, - use-symbolic-message-instead, - missing-class-docstring, - missing-function-docstring, - missing-module-docstring, - fixme - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member - - -[METHOD_ARGS] - -# List of qualified names (i.e., library.method) which require a timeout -# parameter e.g. 'requests.api.get,requests.api.post' -timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME, - XXX, - TODO - -# Regular expression of note tags to take in consideration. -notes-rgx= - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit,argparse.parse_error - - -[REPORTS] - -# Python expression which should return a score less than or equal to 10. You -# have access to the variables 'fatal', 'error', 'warning', 'refactor', -# 'convention', and 'info' which contain the number of messages in each -# category, as well as 'statement' which is the total number of statements -# analyzed. This score is used by the global evaluation report (RP0004). -evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -#output-format= - -# Tells whether to display a full report or only the messages. -reports=no - -# Activate the evaluation score. -score=yes - - -[SIMILARITIES] - -# Comments are removed from the similarity computation -ignore-comments=yes - -# Docstrings are removed from the similarity computation -ignore-docstrings=yes - -# Imports are removed from the similarity computation -ignore-imports=yes - -# Signatures are removed from the similarity computation -ignore-signatures=yes - -# Minimum lines number of a similarity. -min-similarity-lines=16 - - -[SPELLING] - -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions=4 - -# Spelling dictionary name. No available dictionaries : You need to install -# both the python package and the system dependency for enchant to work.. -spelling-dict= - -# List of comma separated words that should be considered directives if they -# appear at the beginning of a comment and should not be checked. -spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains the private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to the private dictionary (see the -# --spelling-private-dict-file option) instead of raising a message. -spelling-store-unknown-words=no - - -[STRING] - -# This flag controls whether inconsistent-quotes generates a warning when the -# character used as a quote delimiter is used inconsistently within a module. -check-quote-consistency=no - -# This flag controls whether the implicit-str-concat should generate a warning -# on implicit string concatenation in sequences defined over several lines. -check-str-concat-over-line-jumps=no - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of symbolic message names to ignore for Mixin members. -ignored-checks-for-mixins=no-member, - not-async-context-manager, - not-context-manager, - attribute-defined-outside-init - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - -# Regex pattern to define which classes are considered mixins. -mixin-class-rgx=.*[Mm]ixin - -# List of decorators that change the signature of a decorated function. -signature-mutators= - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid defining new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of names allowed to shadow builtins -allowed-redefined-builtins= - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_, - _cb - -# A regular expression matching the name of dummy variables (i.e. expected to -# not be used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io diff --git a/CMakeLists.txt b/CMakeLists.txt index 0196d36e..8e8eee53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -310,7 +310,7 @@ target_sources(lego1 PRIVATE LEGO1/lego/sources/misc/legostorage.cpp LEGO1/lego/sources/misc/legotexture.cpp LEGO1/lego/sources/misc/legotree.cpp - LEGO1/lego/sources/misc/legounknown.cpp + LEGO1/lego/sources/misc/legospline.cpp ) target_include_directories(lego1 PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1/omni/include" "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAKE_SOURCE_DIR}/LEGO1/lego/sources") diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index 6b39de3f..4d1ac98e 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -29,18 +29,18 @@ class Act2Actor : public LegoAnimActor { void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 // FUNCTION: LEGO1 0x1001a180 - MxS32 VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) override + MxS32 CheckIntersections(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) override { if (m_animatingHit) { return 0; } - return LegoAnimActor::VTable0x68(p_v1, p_v2, p_v3); + return LegoAnimActor::CheckIntersections(p_v1, p_v2, p_v3); } // vtable+0x68 void Animate(float p_time) override; // vtable+0x70 MxResult HitActor(LegoPathActor*, MxBool) override; // vtable+0x94 - MxResult VTable0x9c() override; // vtable+0x9c + MxResult CalculateSpline() override; // vtable+0x9c MxS32 NextTargetLocation() override; // vtable+0xa0 void InitializeNextShot(); diff --git a/LEGO1/lego/legoomni/include/act3actors.h b/LEGO1/lego/legoomni/include/act3actors.h index 99b4c80b..99c02776 100644 --- a/LEGO1/lego/legoomni/include/act3actors.h +++ b/LEGO1/lego/legoomni/include/act3actors.h @@ -57,7 +57,7 @@ class Act3Actor : public LegoAnimActor { public: Act3Actor(); - MxU32 VTable0x90(float p_time, Matrix4& p_transform) override; // vtable+0x90 + MxU32 StepState(float p_time, Matrix4& p_transform) override; // vtable+0x90 MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 // FUNCTION: LEGO1 0x100431b0 @@ -105,7 +105,7 @@ class Act3Cop : public Act3Actor { void ParseAction(char* p_extra) override; // vtable+0x20 void Animate(float p_time) override; // vtable+0x70 MxResult HitActor(LegoPathActor*, MxBool) override; // vtable+0x94 - MxResult VTable0x9c() override; // vtable+0x9c + MxResult CalculateSpline() override; // vtable+0x9c MxFloat GetUnknown0x20() { return m_unk0x20; } @@ -142,8 +142,8 @@ class Act3Brickster : public Act3Actor { LegoPathBoundary*& p_boundary, LegoOrientedEdge*& p_edge, float& p_unk0xe4 - ) override; // vtable+0x98 - MxResult VTable0x9c() override; // vtable+0x9c + ) override; // vtable+0x98 + MxResult CalculateSpline() override; // vtable+0x9c MxFloat GetUnknown0x20() { return m_unk0x20; } MxFloat GetUnknown0x24() { return m_unk0x24; } diff --git a/LEGO1/lego/legoomni/include/act3ammo.h b/LEGO1/lego/legoomni/include/act3ammo.h index e80aa6b0..8312877a 100644 --- a/LEGO1/lego/legoomni/include/act3ammo.h +++ b/LEGO1/lego/legoomni/include/act3ammo.h @@ -14,7 +14,7 @@ class Act3Ammo : public LegoPathActor { c_pizza = 0x01, c_donut = 0x02, c_valid = 0x04, - c_bit4 = 0x08, + c_withoutBoundary = 0x08, c_sharkFood = 0x10 }; @@ -28,10 +28,10 @@ class Act3Ammo : public LegoPathActor { MxU32 IsValid() { return m_ammoFlag & c_valid; } // FUNCTION: BETA10 0x100177b0 - Mx3DPointFloat* GetUnknown0x160() { return m_eq; } + Mx3DPointFloat* GetCoefficients() { return m_coefficients; } // FUNCTION: BETA10 0x100177e0 - MxFloat* GetUnknown0x19c() { return &m_unk0x19c; } + MxFloat* GetApexParameter() { return &m_apexParameter; } // FUNCTION: BETA10 0x1001fbd0 void SetValid(MxBool p_valid) @@ -51,18 +51,18 @@ class Act3Ammo : public LegoPathActor { MxU32 IsDonut() { return m_ammoFlag & c_donut; } // FUNCTION: BETA10 0x1001fcb0 - void SetBit4(MxBool p_bit4) + void SetShootWithoutBoundary(MxBool p_withoutBoundary) { - if (p_bit4) { - m_ammoFlag |= c_bit4; + if (p_withoutBoundary) { + m_ammoFlag |= c_withoutBoundary; } else { - m_ammoFlag &= ~c_bit4; + m_ammoFlag &= ~c_withoutBoundary; } } // FUNCTION: BETA10 0x10021d90 - MxU32 IsBit4() { return m_ammoFlag & c_bit4; } + MxU32 IsShootWithoutBoundary() { return m_ammoFlag & c_withoutBoundary; } void SetSharkFood(MxBool p_sharkFood) { @@ -76,29 +76,29 @@ class Act3Ammo : public LegoPathActor { MxU32 IsSharkFood() { return m_ammoFlag & c_sharkFood; } - MxFloat GetUnknown0x158() { return m_unk0x158; } + MxFloat GetRotateTimeout() { return m_rotateTimeout; } - void SetUnknown0x158(MxFloat p_unk0x158) { m_unk0x158 = p_unk0x158; } + void SetRotateTimeout(MxFloat p_rotateTimeout) { m_rotateTimeout = p_rotateTimeout; } MxResult Remove(); MxResult Create(Act3* p_world, MxU32 p_isPizza, MxS32 p_index); - MxResult FUN_10053b40(const Vector3& p_srcLoc, const Vector3& p_srcDir, const Vector3& p_srcUp); - MxResult FUN_10053cb0(LegoPathController* p_p, LegoPathBoundary* p_boundary, MxFloat p_unk0x19c); - MxResult FUN_10053d30(LegoPathController* p_p, MxFloat p_unk0x19c); + MxResult CalculateArc(const Vector3& p_srcLoc, const Vector3& p_srcDir, const Vector3& p_srcUp); + MxResult Shoot(LegoPathController* p_p, LegoPathBoundary* p_boundary, MxFloat p_apexParameter); + MxResult Shoot(LegoPathController* p_p, MxFloat p_apexParameter); // SYNTHETIC: LEGO1 0x10053880 // Act3Ammo::`scalar deleting destructor' private: - MxResult FUN_10053db0(float p_param1, Matrix4& p_param2); + MxResult CalculateTransformOnCurve(float p_curveParameter, Matrix4& p_transform); - static Mx3DPointFloat g_unk0x10104f08; + static Mx3DPointFloat g_hitTranslation; - MxU16 m_ammoFlag; // 0x154 - MxFloat m_unk0x158; // 0x158 - Act3* m_world; // 0x15c - Mx3DPointFloat m_eq[3]; // 0x160 - MxFloat m_unk0x19c; // 0x19c + MxU16 m_ammoFlag; // 0x154 + MxFloat m_rotateTimeout; // 0x158 + Act3* m_world; // 0x15c + Mx3DPointFloat m_coefficients[3]; // 0x160 + MxFloat m_apexParameter; // 0x19c }; #endif // ACT3AMMO_H diff --git a/LEGO1/lego/legoomni/include/doors.h b/LEGO1/lego/legoomni/include/doors.h index 5aad2dba..6f65de7f 100644 --- a/LEGO1/lego/legoomni/include/doors.h +++ b/LEGO1/lego/legoomni/include/doors.h @@ -10,7 +10,7 @@ class LegoROI; // SIZE 0x1f8 class Doors : public LegoPathActor { public: - Doors() : m_unk0x154(0), m_ltDoor(NULL), m_rtDoor(NULL), m_unk0x1f4(0) {} + Doors() : m_state(0), m_ltDoor(NULL), m_rtDoor(NULL), m_angle(0) {} // FUNCTION: LEGO1 0x1000e430 // FUNCTION: BETA10 0x100a7f20 @@ -29,19 +29,25 @@ class Doors : public LegoPathActor { void ParseAction(char* p_extra) override; // vtable+0x20 void Animate(float p_time) override; // vtable+0x70 MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 - virtual MxFloat VTable0xcc(float p_time); // vtable+0xcc + virtual MxFloat CalculateAngle(float p_time); // vtable+0xcc // SYNTHETIC: LEGO1 0x1000e580 // Doors::`scalar deleting destructor' private: - undefined4 m_unk0x154; // 0x154 - MxFloat m_unk0x158; // 0x158 - LegoROI* m_ltDoor; // 0x15c - LegoROI* m_rtDoor; // 0x160 - MxMatrix m_ltDoorLocal; // 0x164 - MxMatrix m_rtDoorLocal; // 0x1ac - MxFloat m_unk0x1f4; // 0x1f4 + enum { + e_none = 0, + e_closed = 1, + e_cycling = 2, + }; + + undefined4 m_state; // 0x154 + MxFloat m_hitTime; // 0x158 + LegoROI* m_ltDoor; // 0x15c + LegoROI* m_rtDoor; // 0x160 + MxMatrix m_ltDoorOriginalLocal; // 0x164 + MxMatrix m_rtDoorOriginalLocal; // 0x1ac + MxFloat m_angle; // 0x1f4 }; #endif // DOORS_H diff --git a/LEGO1/lego/legoomni/include/helicopter.h b/LEGO1/lego/legoomni/include/helicopter.h index 8496faf9..9f161c7e 100644 --- a/LEGO1/lego/legoomni/include/helicopter.h +++ b/LEGO1/lego/legoomni/include/helicopter.h @@ -69,7 +69,7 @@ class Helicopter : public IslePathActor { MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 void Animate(float p_time) override; // vtable+0x70 - void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 + void ApplyTransform(Matrix4& p_transform) override; // vtable+0x74 MxLong HandleClick() override; // vtable+0xcc MxLong HandleControl(LegoControlManagerNotificationParam& p_param) override; // vtable+0xd4 MxLong HandleEndAnim(LegoEndAnimNotificationParam& p_param) override; // vtable+0xd8 diff --git a/LEGO1/lego/legoomni/include/islepathactor.h b/LEGO1/lego/legoomni/include/islepathactor.h index 46630e29..d1966b9c 100644 --- a/LEGO1/lego/legoomni/include/islepathactor.h +++ b/LEGO1/lego/legoomni/include/islepathactor.h @@ -102,10 +102,10 @@ class IslePathActor : public LegoPathActor { // FUNCTION: LEGO1 0x10002e00 virtual MxLong HandlePathStruct(LegoPathStructNotificationParam&) { return 0; } // vtable+0xdc - virtual void Enter(); // vtable+0xe0 - virtual void Exit(); // vtable+0xe4 - virtual void SpawnPlayer(LegoGameState::Area p_area, MxBool p_enter, MxU8 p_flags); // vtable+0xe8 - virtual void VTable0xec(MxMatrix p_transform, LegoPathBoundary* p_boundary, MxBool p_reset); // vtable+0xec + virtual void Enter(); // vtable+0xe0 + virtual void Exit(); // vtable+0xe4 + virtual void SpawnPlayer(LegoGameState::Area p_area, MxBool p_enter, MxU8 p_flags); // vtable+0xe8 + virtual void UpdateWorld(MxMatrix p_transform, LegoPathBoundary* p_boundary, MxBool p_reset); // vtable+0xec // FUNCTION: LEGO1 0x10002e10 ~IslePathActor() override { IslePathActor::Destroy(TRUE); } @@ -129,7 +129,7 @@ class IslePathActor : public LegoPathActor { MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 void Destroy(MxBool p_fromDestructor) override; // vtable+0x1c - void FUN_1001b660(); + void TurnAround(); void SetWorld(LegoWorld* p_world) { m_world = p_world; } diff --git a/LEGO1/lego/legoomni/include/legoactioncontrolpresenter.h b/LEGO1/lego/legoomni/include/legoactioncontrolpresenter.h index 3b3193bf..ec142d22 100644 --- a/LEGO1/lego/legoomni/include/legoactioncontrolpresenter.h +++ b/LEGO1/lego/legoomni/include/legoactioncontrolpresenter.h @@ -10,7 +10,7 @@ // SIZE 0x68 class LegoActionControlPresenter : public MxMediaPresenter { public: - LegoActionControlPresenter() : m_unk0x50(Extra::ActionType::e_none) {} + LegoActionControlPresenter() : m_actionType(Extra::ActionType::e_none) {} ~LegoActionControlPresenter() override { Destroy(TRUE); } // vtable+0x00 // FUNCTION: BETA10 0x100a7840 @@ -40,9 +40,9 @@ class LegoActionControlPresenter : public MxMediaPresenter { virtual void Destroy(MxBool p_fromDestructor); // vtable+0x5c private: - Extra::ActionType m_unk0x50; // 0x50 - MxString m_unk0x54; // 0x54 - undefined4 m_unk0x64; // 0x64 + Extra::ActionType m_actionType; // 0x50 + MxString m_sourceName; // 0x54 + undefined4 m_streamId; // 0x64 }; // SYNTHETIC: LEGO1 0x1000d1d0 diff --git a/LEGO1/lego/legoomni/include/legoanimactor.h b/LEGO1/lego/legoomni/include/legoanimactor.h index bfe03344..d774a897 100644 --- a/LEGO1/lego/legoomni/include/legoanimactor.h +++ b/LEGO1/lego/legoomni/include/legoanimactor.h @@ -42,10 +42,10 @@ class LegoAnimActor : public virtual LegoPathActor { ~LegoAnimActor() override; - void ParseAction(char* p_extra) override; // vtable+0x20 - void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 - void Animate(float p_time) override; // vtable+0x70 - void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 + void ParseAction(char* p_extra) override; // vtable+0x20 + void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 + void Animate(float p_time) override; // vtable+0x70 + void ApplyTransform(Matrix4& p_transform) override; // vtable+0x74 virtual MxResult GetTimeInCycle(float& p_timeInCycle); virtual MxResult AnimateWithTransform(float p_time, Matrix4& p_transform); diff --git a/LEGO1/lego/legoomni/include/legoanimmmpresenter.h b/LEGO1/lego/legoomni/include/legoanimmmpresenter.h index 5c972176..cbd9232a 100644 --- a/LEGO1/lego/legoomni/include/legoanimmmpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimmmpresenter.h @@ -61,7 +61,7 @@ class LegoAnimMMPresenter : public MxCompositePresenter { void ParseExtra() override; // vtable+0x30 MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c void EndAction() override; // vtable+0x40 - void VTable0x60(MxPresenter* p_presenter) override; // vtable+0x60 + void AdvanceSerialAction(MxPresenter* p_presenter) override; // vtable+0x60 // SYNTHETIC: LEGO1 0x1004aa40 // LegoAnimMMPresenter::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 6e983144..0cf49100 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -62,21 +62,27 @@ class LegoAnimPresenter : public MxVideoPresenter { return !strcmp(p_name, LegoAnimPresenter::ClassName()) || MxVideoPresenter::IsA(p_name); } - void ReadyTickle() override; // vtable+0x18 - void StartingTickle() override; // vtable+0x1c - void StreamingTickle() override; // vtable+0x20 - void DoneTickle() override; // vtable+0x2c - void ParseExtra() override; // vtable+0x30 - MxResult AddToManager() override; // vtable+0x34 - void Destroy() override; // vtable+0x38 - MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c - void EndAction() override; // vtable+0x40 - void PutFrame() override; // vtable+0x6c - virtual MxResult CreateAnim(MxStreamChunk* p_chunk); // vtable+0x88 - virtual void VTable0x8c(); // vtable+0x8c - virtual void VTable0x90(); // vtable+0x90 - virtual MxU32 VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3); // vtable+0x94 - virtual MxResult VTable0x98(LegoPathBoundary* p_boundary); // vtable+0x98 + void ReadyTickle() override; // vtable+0x18 + void StartingTickle() override; // vtable+0x1c + void StreamingTickle() override; // vtable+0x20 + void DoneTickle() override; // vtable+0x2c + void ParseExtra() override; // vtable+0x30 + MxResult AddToManager() override; // vtable+0x34 + void Destroy() override; // vtable+0x38 + MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c + void EndAction() override; // vtable+0x40 + void PutFrame() override; // vtable+0x6c + virtual MxResult CreateAnim(MxStreamChunk* p_chunk); // vtable+0x88 + virtual void AddToWorld(); // vtable+0x8c + virtual void RemoveFromWorld(); // vtable+0x90 + virtual MxU32 Intersect( + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint + ); // vtable+0x94 + virtual MxResult AddActors(LegoPathBoundary* p_boundary); // vtable+0x98 // FUNCTION: LEGO1 0x1000c990 virtual LegoROI** GetROIMap(MxU32& p_roiMapSize) @@ -85,47 +91,47 @@ class LegoAnimPresenter : public MxVideoPresenter { return m_roiMap; } // vtable+0x9c - virtual void VTable0xa0(Matrix4& p_matrix); // vtable+0xa0 + virtual void SetTransform(Matrix4& p_matrix); // vtable+0xa0 - MxResult FUN_1006afc0(MxMatrix*& p_matrix, float p_und); - MxResult FUN_1006b140(LegoROI* p_roi); - void FUN_1006c7a0(); + MxResult GetTransforms(MxMatrix*& p_matrix, float p_time); + MxResult CopyTransform(LegoROI* p_roi); + void ApplyFinishedTransform(); const char* GetActionObjectName(); void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; } // FUNCTION: BETA10 0x1005aad0 - void SetUnknown0x0cTo1() { m_unk0x9c = 1; } + void SetRoiTransformApplied() { m_roiTransformApplied = 1; } // FUNCTION: BETA10 0x1005ab00 - void SetUnknown0xa0(Matrix4* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } + void SetRoiTransform(Matrix4* p_roiTransform) { m_roiTransform = p_roiTransform; } LegoAnim* GetAnimation() { return m_anim; } protected: void Init(); void Destroy(MxBool p_fromDestructor); - LegoChar* FUN_10069150(const LegoChar* p_und1); - void FUN_100692b0(); - void FUN_100695c0(); + LegoChar* GetActorName(const LegoChar* p_name); + void CreateManagedActors(); + void CreateSceneROIs(); LegoChar* GetVariableOrIdentity(const LegoChar* p_varName, const LegoChar* p_prefix); - LegoBool FUN_100698b0(const CompoundObject& p_rois, const LegoChar* p_und2); + LegoBool AppendROIToScene(const CompoundObject& p_rois, const LegoChar* p_varName); LegoROI* FindROI(const LegoChar* p_name); - void FUN_10069b10(); + void BuildROIMap(); void UpdateStructMapAndROIIndex(LegoAnimStructMap& p_map, LegoTreeNode* p_node, LegoROI* p_roi); void UpdateStructMapAndROIIndexForNode( LegoAnimStructMap& p_map, LegoAnimNodeData* p_data, - const LegoChar* p_und, + const LegoChar* p_key, LegoROI* p_roi ); - void FUN_1006aa60(); - void FUN_1006ab70(); - LegoBool FUN_1006aba0(); - MxBool FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi); + void ReleaseManagedActors(); + void AppendManagedActors(); + LegoBool VerifyAnimationTree(); + MxBool VerifyAnimationNode(LegoTreeNode* p_node, LegoROI* p_roi); void SubstituteVariables(); - void FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix); - void FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix); + void ApplyTransform(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix); + void ApplyTransformWithVisibilityAndCam(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix); void SetDisabled(MxBool p_disabled); LegoAnim* m_anim; // 0x64 @@ -133,27 +139,27 @@ class LegoAnimPresenter : public MxVideoPresenter { MxU32 m_roiMapSize; // 0x6c LegoROIList* m_sceneROIs; // 0x70 LegoROIList* m_managedActors; // 0x74 - Matrix4* m_unk0x78; // 0x78 + Matrix4* m_transform; // 0x78 MxU32 m_flags; // 0x7c LegoWorld* m_currentWorld; // 0x80 MxAtomId m_worldAtom; // 0x84 MxS32 m_worldId; // 0x88 - LegoROI** m_unk0x8c; // 0x8c - char** m_unk0x90; // 0x90 - MxU8 m_unk0x94; // 0x94 - MxBool m_unk0x95; // 0x95 - MxBool m_unk0x96; // 0x96 + LegoROI** m_ptAtCamROI; // 0x8c + char** m_ptAtCamNames; // 0x90 + MxU8 m_ptAtCamCount; // 0x94 + MxBool m_animationFinished; // 0x95 + MxBool m_localActors; // 0x96 undefined m_unk0x97; // 0x97 LegoAnimSubstMap* m_substMap; // 0x98 - MxS16 m_unk0x9c; // 0x9c - Matrix4* m_unk0xa0; // 0xa0 + MxS16 m_roiTransformApplied; // 0x9c + Matrix4* m_roiTransform; // 0xa0 // SYNTHETIC: LEGO1 0x10068650 // LegoAnimPresenter::`scalar deleting destructor' public: - float m_unk0xa4; // 0xa4 - Mx3DPointFloat m_unk0xa8; // 0xa8 + float m_boundingRadius; // 0xa4 + Mx3DPointFloat m_centerPoint; // 0xa8 }; // VTABLE: LEGO1 0x100d4900 @@ -231,16 +237,16 @@ class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter { void PutFrame() override; // vtable+0x6c MxResult CreateAnim(MxStreamChunk* p_chunk) override; // vtable+0x88 - void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value); + void CreateROIAndBuildMap(LegoAnimActor* p_actor, MxFloat p_worldSpeed); - void DecrementUnknown0xd4() + void DecrementWorldRefCounter() { - if (m_unk0xd4) { - --m_unk0xd4; + if (m_worldRefCounter) { + --m_worldRefCounter; } } - undefined2 GetUnknown0xd4() { return m_unk0xd4; } + MxS16 GetWorldRefCounter() { return m_worldRefCounter; } // SYNTHETIC: LEGO1 0x1006cfe0 // LegoLocomotionAnimPresenter::`scalar deleting destructor' @@ -254,7 +260,7 @@ class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter { LegoROIMapList* m_roiMapList; // 0xc8 MxS32 m_unk0xcc; // 0xcc MxS32 m_unk0xd0; // 0xd0 - undefined2 m_unk0xd4; // 0xd4 + MxS16 m_worldRefCounter; // 0xd4 }; class LegoPathBoundary; @@ -279,10 +285,10 @@ class LegoHideAnimPresenter : public LegoLoopingAnimPresenter { ~LegoHideAnimPresenter() override; // FUNCTION: LEGO1 0x1006d860 - void VTable0x8c() override {} // vtable+0x8c + void AddToWorld() override {} // vtable+0x8c // FUNCTION: LEGO1 0x1006d870 - void VTable0x90() override {} // vtable+0x90 + void RemoveFromWorld() override {} // vtable+0x90 // FUNCTION: BETA10 0x1005d4a0 static const char* HandlerClassName() @@ -311,7 +317,7 @@ class LegoHideAnimPresenter : public LegoLoopingAnimPresenter { void EndAction() override; // vtable+0x40 void PutFrame() override; // vtable+0x6c - void FUN_1006db40(LegoTime p_time); + void ApplyVisibility(LegoTime p_time); // SYNTHETIC: LEGO1 0x1006d9d0 // LegoHideAnimPresenter::`scalar deleting destructor' @@ -319,10 +325,10 @@ class LegoHideAnimPresenter : public LegoLoopingAnimPresenter { private: void Init(); void Destroy(MxBool p_fromDestructor); - void FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time); - void FUN_1006dc10(); - void FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node); - void FUN_1006e470( + void ApplyVisibility(LegoTreeNode* p_node, LegoTime p_time); + void AssignIndiciesWithMap(); + void BuildMap(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node); + void CheckedAdd( LegoHideAnimStructMap& p_map, LegoAnimNodeData* p_data, const char* p_name, diff --git a/LEGO1/lego/legoomni/include/legoeventnotificationparam.h b/LEGO1/lego/legoomni/include/legoeventnotificationparam.h index 5569280c..e4f866e1 100644 --- a/LEGO1/lego/legoomni/include/legoeventnotificationparam.h +++ b/LEGO1/lego/legoomni/include/legoeventnotificationparam.h @@ -43,8 +43,13 @@ class LegoEventNotificationParam : public MxNotificationParam { { } + // FUNCTION: BETA10 0x10026070 LegoROI* GetROI() { return m_roi; } + + // FUNCTION: BETA10 0x1006aab0 MxU8 GetModifier() { return m_modifier; } + + // FUNCTION: BETA10 0x100179a0 SDL_Keycode GetKey() const { return m_key; } // FUNCTION: LEGO1 0x10012190 diff --git a/LEGO1/lego/legoomni/include/legoextraactor.h b/LEGO1/lego/legoomni/include/legoextraactor.h index 05ee8510..bebcbcec 100644 --- a/LEGO1/lego/legoomni/include/legoextraactor.h +++ b/LEGO1/lego/legoomni/include/legoextraactor.h @@ -36,45 +36,52 @@ class LegoExtraActor : public virtual LegoAnimActor { return !strcmp(p_name, LegoExtraActor::ClassName()) || LegoAnimActor::IsA(p_name); } - void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 - MxS32 VTable0x68(Vector3& p_point1, Vector3& p_point2, Vector3& p_point3) override; // vtable+0x68 - inline MxU32 VTable0x6c( + void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 + MxS32 CheckIntersections(Vector3& p_rayOrigin, Vector3& p_rayEnd, Vector3& p_intersectionPoint) + override; // vtable+0x68 + inline MxU32 CheckPresenterAndActorIntersections( LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 - ) override; // vtable+0x6c - void Animate(float p_time) override; // vtable+0x70 - void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 - MxU32 VTable0x90(float p_time, Matrix4& p_matrix) override; // vtable+0x90 - MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 - MxResult VTable0x9c() override; // vtable+0x9c - void VTable0xa4(MxBool& p_und1, MxS32& p_und2) override; // vtable+0xa4 - void VTable0xc4() override; // vtable+0xc4 + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint + ) override; // vtable+0x6c + void Animate(float p_time) override; // vtable+0x70 + void ApplyTransform(Matrix4& p_transform) override; // vtable+0x74 + MxU32 StepState(float p_time, Matrix4& p_matrix) override; // vtable+0x90 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + MxResult CalculateSpline() override; // vtable+0x9c + void GetWalkingBehavior(MxBool& p_countCounterclockWise, MxS32& p_selectedEdgeIndex) override; // vtable+0xa4 + void VTable0xc4() override; // vtable+0xc4 - virtual MxResult FUN_1002aae0(); + virtual MxResult SwitchDirection(); void Restart(); - inline void FUN_1002ad8a(); + inline void InitializeReassemblyAnim(); - void SetUnknown0x0c(undefined p_unk0x0c) { m_unk0x0c = p_unk0x0c; } + void SetPathWalkingMode(MxU8 p_pathWalkingMode) { m_pathWalkingMode = p_pathWalkingMode; } // SYNTHETIC: LEGO1 0x1002b760 // LegoExtraActor::`scalar deleting destructor' private: - MxFloat m_scheduledTime; // 0x08 - undefined m_unk0x0c; // 0x0c - MxU8 m_axis; // 0x0d - undefined m_unk0x0e; // 0x0e - MxFloat m_prevWorldSpeed; // 0x10 - MxU8 m_whichAnim; // 0x14 - MxU8 m_unk0x15; // 0x15 - MxMatrix m_unk0x18; // 0x18 - LegoAnimActorStruct* m_assAnim; // 0x60 - LegoAnimActorStruct* m_disAnim; // 0x64 + enum { + e_none = 0, + e_disassemble = 1, + e_assemble = 2, + }; + + MxFloat m_scheduledTime; // 0x08 + MxU8 m_pathWalkingMode; // 0x0c + MxU8 m_axis; // 0x0d + MxBool m_animationAtCurrentBoundary; // 0x0e + MxFloat m_prevWorldSpeed; // 0x10 + MxU8 m_reassemblyAnimation; // 0x14 + MxU8 m_hitBlockCounter; // 0x15 + MxMatrix m_localBeforeHit; // 0x18 + LegoAnimActorStruct* m_assAnim; // 0x60 + LegoAnimActorStruct* m_disAnim; // 0x64 }; // GLOBAL: LEGO1 0x100d6be8 diff --git a/LEGO1/lego/legoomni/include/legonavcontroller.h b/LEGO1/lego/legoomni/include/legonavcontroller.h index adbed6a1..974966c6 100644 --- a/LEGO1/lego/legoomni/include/legonavcontroller.h +++ b/LEGO1/lego/legoomni/include/legonavcontroller.h @@ -44,7 +44,7 @@ class LegoNavController : public MxCore { const Vector3& p_curDir, Vector3& p_newPos, Vector3& p_newDir, - const Vector3* p_und + const Vector3* p_up ); static void GetDefaults( @@ -126,36 +126,36 @@ class LegoNavController : public MxCore { float CalculateNewTargetVel(int p_pos, int p_center, float p_max); float CalculateNewAccel(int p_pos, int p_center, float p_max, int p_min); - MxResult ProcessJoystickInput(MxBool& p_und); + MxResult ProcessJoystickInput(MxBool& p_rotatedY); MxResult ProcessKeyboardInput(); - int m_hMax; // 0x08 - int m_vMax; // 0x0c - int m_deadZone; // 0x10 - float m_zeroThreshold; // 0x14 - float m_linearVel; // 0x18 - float m_rotationalVel; // 0x1c - float m_targetLinearVel; // 0x20 - float m_targetRotationalVel; // 0x24 - float m_maxLinearVel; // 0x28 - float m_maxRotationalVel; // 0x2c - float m_linearAccel; // 0x30 - float m_rotationalAccel; // 0x34 - float m_maxLinearAccel; // 0x38 - float m_maxRotationalAccel; // 0x3c - float m_minLinearAccel; // 0x40 - float m_minRotationalAccel; // 0x44 - float m_maxLinearDeccel; // 0x48 - float m_maxRotationalDeccel; // 0x4c - float m_rotSensitivity; // 0x50 - MxBool m_useRotationalVel; // 0x54 - MxTime m_lastTime; // 0x58 - MxBool m_trackDefault; // 0x5c - MxBool m_unk0x5d; // 0x5d - float m_unk0x60; // 0x60 - float m_unk0x64; // 0x64 - float m_unk0x68; // 0x68 - MxBool m_isAccelerating; // 0x6c + int m_hMax; // 0x08 + int m_vMax; // 0x0c + int m_deadZone; // 0x10 + float m_zeroThreshold; // 0x14 + float m_linearVel; // 0x18 + float m_rotationalVel; // 0x1c + float m_targetLinearVel; // 0x20 + float m_targetRotationalVel; // 0x24 + float m_maxLinearVel; // 0x28 + float m_maxRotationalVel; // 0x2c + float m_linearAccel; // 0x30 + float m_rotationalAccel; // 0x34 + float m_maxLinearAccel; // 0x38 + float m_maxRotationalAccel; // 0x3c + float m_minLinearAccel; // 0x40 + float m_minRotationalAccel; // 0x44 + float m_maxLinearDeccel; // 0x48 + float m_maxRotationalDeccel; // 0x4c + float m_rotSensitivity; // 0x50 + MxBool m_useRotationalVel; // 0x54 + MxTime m_lastTime; // 0x58 + MxBool m_trackDefault; // 0x5c + MxBool m_keyPressed; // 0x5d + float m_additionalHeightOffset; // 0x60 + float m_additionalScale; // 0x64 + float m_additionalRotationY; // 0x68 + MxBool m_isAccelerating; // 0x6c // one copy of defaults (these can be set by App.) static int g_defdeadZone; diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 2f1d8862..491e067c 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -2,7 +2,7 @@ #define LEGOPATHACTOR_H #include "legoactor.h" -#include "misc/legounknown.h" +#include "misc/legospline.h" #include "mxtypes.h" struct LegoEdge; @@ -24,9 +24,9 @@ class LegoPathActor : public LegoActor { enum ActorState { // States c_initial = 0, - c_one = 1, - c_two = 2, - c_three = 3, + c_ready = 1, + c_hit = 2, + c_hitAnimation = 3, c_disabled = 4, c_maxState = 255, @@ -37,18 +37,22 @@ class LegoPathActor : public LegoActor { LegoPathActor(); ~LegoPathActor() override; - void ParseAction(char* p_extra) override; // vtable+0x20 - virtual MxS32 VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3); // vtable+0x68 - virtual MxU32 VTable0x6c( + void ParseAction(char* p_extra) override; // vtable+0x20 + virtual MxS32 CheckIntersections( + Vector3& p_rayOrigin, + Vector3& p_rayEnd, + Vector3& p_intersectionPoint + ); // vtable+0x68 + virtual MxU32 CheckPresenterAndActorIntersections( LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 - ); // vtable+0x6c - virtual void Animate(float p_time); // vtable+0x70 - virtual void VTable0x74(Matrix4& p_transform); // vtable+0x74 + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint + ); // vtable+0x6c + virtual void Animate(float p_time); // vtable+0x70 + virtual void ApplyTransform(Matrix4& p_transform); // vtable+0x74 // FUNCTION: LEGO1 0x10002d20 // FUNCTION: BETA10 0x1000f500 @@ -58,33 +62,33 @@ class LegoPathActor : public LegoActor { // FUNCTION: BETA10 0x1000f530 virtual MxBool GetUserNavFlag() { return m_userNavFlag; } // vtable+0x7c - virtual MxResult VTable0x80( - const Vector3& p_point1, - Vector3& p_point2, - Vector3& p_point3, - Vector3& p_point4 + virtual MxResult SetSpline( + const Vector3& p_start, + Vector3& p_tangentAtStart, + Vector3& p_end, + Vector3& p_tangentAtEnd ); // vtable+0x80 - virtual MxResult VTable0x84( + virtual MxResult SetTransformAndDestinationFromPoints( LegoPathBoundary* p_boundary, float p_time, - Vector3& p_p1, - Vector3& p_p4, + Vector3& p_start, + Vector3& p_direction, LegoOrientedEdge* p_destEdge, float p_destScale ); // vtable+0x84 - virtual MxResult VTable0x88( + virtual MxResult SetTransformAndDestinationFromEdge( LegoPathBoundary* p_boundary, float p_time, LegoEdge& p_srcEdge, float p_srcScale, LegoOrientedEdge& p_destEdge, float p_destScale - ); // vtable+0x88 - virtual MxS32 VTable0x8c(float p_time, Matrix4& p_transform); // vtable+0x8c + ); // vtable+0x88 + virtual MxS32 CalculateTransform(float p_time, Matrix4& p_transform); // vtable+0x8c // FUNCTION: LEGO1 0x10002d40 // FUNCTION: BETA10 0x1000f560 - virtual MxU32 VTable0x90(float, Matrix4&) { return FALSE; } // vtable+0x90 + virtual MxU32 StepState(float, Matrix4&) { return FALSE; } // vtable+0x90 // FUNCTION: LEGO1 0x10002d50 // FUNCTION: BETA10 0x1000f800 @@ -93,16 +97,16 @@ class LegoPathActor : public LegoActor { virtual void SwitchBoundary( LegoPathBoundary*& p_boundary, LegoOrientedEdge*& p_edge, - float& p_unk0xe4 - ); // vtable+0x98 - virtual MxResult VTable0x9c(); // vtable+0x9c + float& p_scale + ); // vtable+0x98 + virtual MxResult CalculateSpline(); // vtable+0x9c // FUNCTION: LEGO1 0x10002d60 // FUNCTION: BETA10 0x1000f820 virtual MxS32 NextTargetLocation() { return 0; } // vtable+0xa0 - virtual void VTable0xa4(MxBool& p_und1, MxS32& p_und2); // vtable+0xa4 - virtual void VTable0xa8(); // vtable+0xa8 + virtual void GetWalkingBehavior(MxBool& p_countCounterclockWise, MxS32& p_selectedEdgeIndex); // vtable+0xa4 + virtual void ApplyLocal2World(); // vtable+0xa8 // FUNCTION: LEGO1 0x10002d70 // FUNCTION: BETA10 0x1000f580 @@ -114,26 +118,32 @@ class LegoPathActor : public LegoActor { // FUNCTION: LEGO1 0x10002d90 // FUNCTION: BETA10 0x1000f5e0 - virtual MxFloat VTable0xb4() { return m_unk0x140; } // vtable+0xb4 + virtual MxFloat GetWallHitDirectionFactor() { return m_wallHitDirectionFactor; } // vtable+0xb4 // FUNCTION: LEGO1 0x10002da0 // FUNCTION: BETA10 0x1000f610 - virtual MxFloat VTable0xb8() { return m_unk0x144; } // vtable+0xb8 + virtual MxFloat GetWallHitDampening() { return m_wallHitDampening; } // vtable+0xb8 // FUNCTION: LEGO1 0x10002db0 // FUNCTION: BETA10 0x1000f640 - virtual void VTable0xbc(MxFloat p_unk0x140) { m_unk0x140 = p_unk0x140; } // vtable+0xbc + virtual void SetWallHitDirectionFactor(MxFloat p_wallHitDirectionFactor) + { + m_wallHitDirectionFactor = p_wallHitDirectionFactor; + } // vtable+0xbc // FUNCTION: LEGO1 0x10002dc0 // FUNCTION: BETA10 0x1000f670 - virtual void VTable0xc0(MxFloat p_unk0x144) { m_unk0x144 = p_unk0x144; } // vtable+0xc0 + virtual void SetWallHitDampening(MxFloat p_wallHitDampening) + { + m_wallHitDampening = p_wallHitDampening; + } // vtable+0xc0 // FUNCTION: LEGO1 0x10002dd0 // FUNCTION: BETA10 0x1000f6a0 virtual void VTable0xc4() {} // vtable+0xc4 // FUNCTION: LEGO1 0x10002de0 - virtual void VTable0xc8(MxU8 p_unk0x148) { m_unk0x148 = p_unk0x148; } // vtable+0xc8 + virtual void SetCanRotate(MxU8 p_canRotate) { m_canRotate = p_canRotate; } // vtable+0xc8 // FUNCTION: LEGO1 0x1000c430 // FUNCTION: BETA10 0x10012790 @@ -158,7 +168,7 @@ class LegoPathActor : public LegoActor { LegoPathController* GetController() { return m_pathController; } MxBool GetCollideBox() { return m_collideBox; } - MxFloat GetLastTime() { return m_lastTime; } + MxFloat GetTransformTime() { return m_transformTime; } MxFloat GetActorTime() { return m_actorTime; } void SetBoundary(LegoPathBoundary* p_boundary) { m_boundary = p_boundary; } @@ -167,7 +177,7 @@ class LegoPathActor : public LegoActor { void SetActorState(MxU32 p_actorState) { m_actorState = p_actorState; } void SetController(LegoPathController* p_pathController) { m_pathController = p_pathController; } - void SetLastTime(MxFloat p_lastTime) { m_lastTime = p_lastTime; } + void SetTransformTime(MxFloat p_transformTime) { m_transformTime = p_transformTime; } void SetActorTime(MxFloat p_actorTime) { m_actorTime = p_actorTime; } void UpdatePlane(LegoNamedPlane& p_namedPlane); @@ -178,42 +188,42 @@ class LegoPathActor : public LegoActor { // LegoPathActor::`scalar deleting destructor' protected: - inline MxU32 FUN_1002edd0( - list& p_boundaries, + inline MxU32 CheckIntersectionBothFaces( + list& p_checkedBoundaries, LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3, - MxS32 p_und + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint, + MxS32 p_depth ); MxFloat m_BADuration; // 0x78 - MxFloat m_unk0x7c; // 0x7c + MxFloat m_traveledDistance; // 0x7c MxFloat m_actorTime; // 0x80 - MxFloat m_lastTime; // 0x84 + MxFloat m_transformTime; // 0x84 LegoPathBoundary* m_boundary; // 0x88 - LegoUnknown m_unk0x8c; // 0x8c + LegoSpline m_spline; // 0x8c MxU32 m_actorState; // 0xdc LegoOrientedEdge* m_destEdge; // 0xe0 - MxFloat m_unk0xe4; // 0xe4 + MxFloat m_destScale; // 0xe4 MxBool m_collideBox; // 0xe8 - MxBool m_unk0xe9; // 0xe9 + MxBool m_finishedTravel; // 0xe9 MxBool m_userNavFlag; // 0xea - MxMatrix m_unk0xec; // 0xec + MxMatrix m_local2World; // 0xec LegoPathEdgeContainer* m_grec; // 0x134 LegoPathController* m_pathController; // 0x138 MxFloat m_maxLinearVel; // 0x13c - MxFloat m_unk0x140; // 0x140 - MxFloat m_unk0x144; // 0x144 - MxU8 m_unk0x148; // 0x148 - MxS32 m_unk0x14c; // 0x14c - MxFloat m_unk0x150; // 0x150 + MxFloat m_wallHitDirectionFactor; // 0x140 + MxFloat m_wallHitDampening; // 0x144 + MxU8 m_canRotate; // 0x148 + MxS32 m_lastRotationAngle; // 0x14c + MxFloat m_linearRotationRatio; // 0x150 }; // FUNCTION: LEGO1 0x1002edd0 -// LegoPathActor::FUN_1002edd0 +// LegoPathActor::CheckIntersectionBothFaces // TEMPLATE: LEGO1 0x10018b70 // List::~List diff --git a/LEGO1/lego/legoomni/include/legopathboundary.h b/LEGO1/lego/legoomni/include/legopathboundary.h index d3c1c4e7..c2ea2504 100644 --- a/LEGO1/lego/legoomni/include/legopathboundary.h +++ b/LEGO1/lego/legoomni/include/legopathboundary.h @@ -40,14 +40,20 @@ class LegoPathBoundary : public LegoWEGEdge { MxResult AddActor(LegoPathActor* p_actor); MxResult RemoveActor(LegoPathActor* p_actor); - void CheckAndCallPathTriggers(Vector3& p_point1, Vector3& p_point2, LegoPathActor* p_actor); + void CheckAndCallPathTriggers(Vector3& p_from, Vector3& p_to, LegoPathActor* p_actor); void SwitchBoundary( LegoPathActor* p_actor, LegoPathBoundary*& p_boundary, LegoOrientedEdge*& p_edge, - float& p_unk0xe4 + float& p_scale + ); + MxU32 Intersect( + float p_scale, + Vector3& p_oldPos, + Vector3& p_newPos, + Vector3& p_intersectionPoint, + LegoOrientedEdge*& p_edge ); - MxU32 Intersect(float p_scale, Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, LegoOrientedEdge*& p_edge); MxU32 AddPresenterIfInRange(LegoAnimPresenter* p_presenter); MxU32 RemovePresenter(LegoAnimPresenter* p_presenter); diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 30240fc9..9d09c224 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -109,13 +109,13 @@ class LegoPathController : public MxCore { ); MxResult PlaceActor(LegoPathActor* p_actor); MxResult RemoveActor(LegoPathActor* p_actor); - void FUN_100468f0(LegoAnimPresenter* p_presenter); + void AddPresenterIfInRange(LegoAnimPresenter* p_presenter); void RemovePresenterFromBoundaries(LegoAnimPresenter* p_presenter); - MxResult FUN_10046b30(LegoPathBoundary*& p_boundaries, MxS32& p_numL); + MxResult GetBoundaries(LegoPathBoundary*& p_boundaries, MxS32& p_numL); LegoPathBoundary* GetPathBoundary(const char* p_name); void Enable(MxBool p_enable); - void FUN_10046bb0(LegoWorld* p_world); - MxResult FUN_10048310( + void SetWorld(LegoWorld* p_world); + MxResult FindPath( LegoPathEdgeContainer* p_grec, const Vector3& p_oldPosition, const Vector3& p_oldDirection, @@ -124,17 +124,17 @@ class LegoPathController : public MxCore { const Vector3& p_newDirection, LegoPathBoundary* p_newBoundary, LegoU8 p_mask, - MxFloat* p_param9 + MxFloat* p_distance ); - MxS32 FUN_1004a240( + MxS32 GetNextPathEdge( LegoPathEdgeContainer& p_grec, - Vector3& p_v1, - Vector3& p_v2, + Vector3& p_position, + Vector3& p_direction, float p_f1, LegoOrientedEdge*& p_edge, LegoPathBoundary*& p_boundary ); - MxResult FUN_1004a380( + MxResult FindIntersectionBoundary( Vector3& p_param1, Vector3& p_param2, Mx3DPointFloat* p_param3, @@ -159,7 +159,7 @@ class LegoPathController : public MxCore { static LegoPathBoundary* GetControlBoundaryB(MxS32 p_index) { return g_ctrlBoundariesB[p_index].m_boundary; } private: - void FUN_10046970(); + void AnimateActors(); MxResult Read(LegoStorage* p_storage); MxResult ReadStructs(LegoStorage* p_storage); MxResult ReadEdges(LegoStorage* p_storage); @@ -179,7 +179,7 @@ class LegoPathController : public MxCore { } // FUNCTION: BETA10 0x100c17a0 - static MxU32 FUN_100c17a0(MxFloat p_v1, MxFloat p_v2, MxFloat p_a, MxFloat p_b) + static MxU32 BothSameComparison(MxFloat p_v1, MxFloat p_v2, MxFloat p_a, MxFloat p_b) { assert(IsBetween(p_v1, p_a, p_b)); assert(IsBetween(p_v2, p_a, p_b)); @@ -207,8 +207,8 @@ class LegoPathController : public MxCore { static CtrlBoundary* g_ctrlBoundariesA; static CtrlEdge* g_ctrlEdgesA; - static const char* g_unk0x100f42f0[]; - static const char* g_unk0x100f4330[]; + static const char* g_ctrlBoundariesNamesA[]; + static const char* g_ctrlBoundariesNamesB[]; static CtrlBoundary* g_ctrlBoundariesB; static CtrlEdge* g_ctrlEdgesB; }; @@ -296,58 +296,58 @@ class LegoPathController : public MxCore { // _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Ubound // TEMPLATE: LEGO1 0x100493a0 -// list >::~list > +// list >::~list > // TEMPLATE: LEGO1 0x10049410 -// list >::insert +// list >::insert // TEMPLATE: LEGO1 0x10049470 -// list >::_Buynode +// list >::_Buynode // TEMPLATE: LEGO1 0x100494a0 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::iterator::_Inc +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::iterator::_Inc // TEMPLATE: LEGO1 0x100494e0 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::~_Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::~_Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::insert +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::insert // TEMPLATE: LEGO1 0x10049840 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::iterator::_Dec +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::iterator::_Dec // TEMPLATE: LEGO1 0x10049890 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::erase +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::erase // TEMPLATE: LEGO1 0x10049cf0 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Buynode +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::_Buynode // TEMPLATE: LEGO1 0x10049d50 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Init +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::_Init // TEMPLATE: LEGO1 0x10049e00 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Insert +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::_Insert // TEMPLATE: LEGO1 0x10049d10 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Erase +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::_Erase // TEMPLATE: LEGO1 0x1004a090 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Lrotate +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::_Lrotate // TEMPLATE: LEGO1 0x1004a0f0 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Rrotate +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::_Rrotate // TEMPLATE: LEGO1 0x1004a150 -// List::~List +// List::~List // TEMPLATE: LEGO1 0x1004a1a0 -// Multiset::~Multiset +// Multiset::~Multiset // TEMPLATE: LEGO1 0x1004a1f0 -// multiset >::~multiset > +// multiset >::~multiset > // TEMPLATE: LEGO1 0x1004a760 -// ?_Construct@@YAXPAPAULegoBEWithFloat@@ABQAU1@@Z +// ?_Construct@@YAXPAPAULegoBEWithMidpoint@@ABQAU1@@Z // TEMPLATE: LEGO1 0x1004a780 // ?_Construct@@YAXPAPAULegoPathCtrlEdge@@ABQAU1@@Z @@ -356,7 +356,7 @@ class LegoPathController : public MxCore { // _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Nil // GLOBAL: LEGO1 0x100f4364 -// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Nil +// _Tree >::_Kfn,LegoBEWithMidpointComparator,allocator >::_Nil // clang-format on #endif // LEGOPATHCONTROLLER_H diff --git a/LEGO1/lego/legoomni/include/legopathedgecontainer.h b/LEGO1/lego/legoomni/include/legopathedgecontainer.h index bba8547b..5998f842 100644 --- a/LEGO1/lego/legoomni/include/legopathedgecontainer.h +++ b/LEGO1/lego/legoomni/include/legopathedgecontainer.h @@ -27,56 +27,61 @@ struct LegoBoundaryEdge { }; // SIZE 0x10 -struct LegoBEWithFloat { - LegoBEWithFloat() +struct LegoBEWithMidpoint { + LegoBEWithMidpoint() { m_edge = NULL; m_boundary = NULL; m_next = NULL; - m_unk0x0c = 0.0f; + m_distanceToMidpoint = 0.0f; } // FUNCTION: BETA10 0x100bd9a0 - LegoBEWithFloat(LegoPathCtrlEdge* p_edge, LegoPathBoundary* p_boundary, MxFloat p_unk0x0c) + LegoBEWithMidpoint(LegoPathCtrlEdge* p_edge, LegoPathBoundary* p_boundary, MxFloat p_distanceToMidpoint) { m_edge = p_edge; m_boundary = p_boundary; m_next = NULL; - m_unk0x0c = p_unk0x0c; + m_distanceToMidpoint = p_distanceToMidpoint; } // FUNCTION: BETA10 0x100bd9f0 - LegoBEWithFloat(LegoPathCtrlEdge* p_edge, LegoPathBoundary* p_boundary, LegoBEWithFloat* p_next, MxFloat p_unk0x0c) + LegoBEWithMidpoint( + LegoPathCtrlEdge* p_edge, + LegoPathBoundary* p_boundary, + LegoBEWithMidpoint* p_next, + MxFloat p_distanceToMidpoint + ) { m_edge = p_edge; m_boundary = p_boundary; m_next = p_next; - m_unk0x0c = p_unk0x0c; + m_distanceToMidpoint = p_distanceToMidpoint; } LegoPathCtrlEdge* m_edge; // 0x00 LegoPathBoundary* m_boundary; // 0x04 - LegoBEWithFloat* m_next; // 0x08 - MxFloat m_unk0x0c; // 0x0c + LegoBEWithMidpoint* m_next; // 0x08 + MxFloat m_distanceToMidpoint; // 0x0c - int operator==(LegoBEWithFloat) const { return 0; } - int operator<(LegoBEWithFloat) const { return 0; } + int operator==(LegoBEWithMidpoint) const { return 0; } + int operator<(LegoBEWithMidpoint) const { return 0; } }; -struct LegoBEWithFloatComparator { +struct LegoBEWithMidpointComparator { // FUNCTION: BETA10 0x100bef80 - bool operator()(LegoBEWithFloat* const& p_a, LegoBEWithFloat* const& p_b) const + bool operator()(LegoBEWithMidpoint* const& p_a, LegoBEWithMidpoint* const& p_b) const { - return p_a->m_unk0x0c < p_b->m_unk0x0c; + return p_a->m_distanceToMidpoint < p_b->m_distanceToMidpoint; } }; -typedef multiset LegoBEWithFloatSet; +typedef multiset LegoBEWithMidpointSet; // SIZE 0x3c struct LegoPathEdgeContainer : public list { enum { - c_bit1 = 0x01 + c_hasPath = 0x01 }; // FUNCTION: BETA10 0x100118e0 @@ -87,18 +92,18 @@ struct LegoPathEdgeContainer : public list { } // FUNCTION: BETA10 0x100bd660 - void SetBit1(MxU32 p_set) + void SetPath(MxU32 p_set) { if (p_set) { - m_flags |= c_bit1; + m_flags |= c_hasPath; } else { - m_flags &= ~c_bit1; + m_flags &= ~c_hasPath; } } // FUNCTION: BETA10 0x1001cb50 - MxU32 GetBit1() { return m_flags & c_bit1; } + MxU32 HasPath() { return m_flags & c_hasPath; } Mx3DPointFloat m_position; // 0x0c Mx3DPointFloat m_direction; // 0x20 diff --git a/LEGO1/lego/legoomni/include/legoraceactor.h b/LEGO1/lego/legoomni/include/legoraceactor.h index bc3d54dc..a9ad5fc0 100644 --- a/LEGO1/lego/legoomni/include/legoraceactor.h +++ b/LEGO1/lego/legoomni/include/legoraceactor.h @@ -30,9 +30,13 @@ class LegoRaceActor : public virtual LegoAnimActor { return !strcmp(p_name, LegoRaceActor::ClassName()) || LegoAnimActor::IsA(p_name); } - MxS32 VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) override; // vtable+0x68 - MxU32 VTable0x90(float p_time, Matrix4& p_matrix) override; // vtable+0x90 - MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + MxS32 CheckIntersections( + Vector3& p_rayOrigin, + Vector3& p_rayEnd, + Vector3& p_intersectionPoint + ) override; // vtable+0x68 + MxU32 StepState(float p_time, Matrix4& p_matrix) override; // vtable+0x90 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 virtual MxResult FUN_10014aa0(); diff --git a/LEGO1/lego/legoomni/include/legoracemap.h b/LEGO1/lego/legoomni/include/legoracemap.h index 562581fa..448f11fa 100644 --- a/LEGO1/lego/legoomni/include/legoracemap.h +++ b/LEGO1/lego/legoomni/include/legoracemap.h @@ -26,7 +26,7 @@ class LegoRaceMap : public virtual LegoRaceActor { void Animate(float p_time) override = 0; // vtable+0x70 // LegoRaceMap vtable - virtual void FUN_1005d4b0(); // vtable+0x00 + virtual void UpdateMapLocatorPosition(); // vtable+0x00 // SYNTHETIC: LEGO1 0x10012c50 // LegoRaceMap::`vbase destructor' @@ -35,28 +35,28 @@ class LegoRaceMap : public virtual LegoRaceActor { // LegoRaceMap::`scalar deleting destructor' private: - MxBool m_unk0x08; // 0x08 + MxBool m_mapEnabled; // 0x08 MxStillPresenter* m_stillPresenter; // 0x0c // variable name verified by BETA10 0x100ca82b MxControlPresenter* m_Map_Ctl; // 0x10 // likely an x-offset of the race map in world space - float m_unk0x14; // 0x14 + float m_worldXOffset; // 0x14 // inversely scales the map in x direction (either convert world->screen space or to control the size) - float m_unk0x18; // 0x18 - // likely a y-offset of the race map in world space - float m_unk0x1c; // 0x1c - // inversely scales the map in y direction (either convert world->screen space or to control the size) - float m_unk0x20; // 0x20 + float m_worldXScale; // 0x18 + // likely a z-offset of the race map in world space + float m_worldZOffset; // 0x1c + // inversely scales the map in z direction (either convert world->screen space or to control the size) + float m_worldZScale; // 0x20 // scales the map in x direction (either convert world->screen space or to change the size) - float m_unk0x24; // 0x24 + float m_screenXScale; // 0x24 // scales the map in y direction (either convert world->screen space or to change the size) - float m_unk0x28; // 0x28 + float m_screenYScale; // 0x28 // likely an x-offset of the race map in screen space - float m_unk0x2c; // 0x2c + float m_screenXOffset; // 0x2c // likely a y-offset of the race map in screen space - float m_unk0x30; // 0x30 + float m_screenYOffset; // 0x30 }; // GLOBAL: LEGO1 0x100d8848 diff --git a/LEGO1/lego/legoomni/include/legoracers.h b/LEGO1/lego/legoomni/include/legoracers.h index 3c8ffe07..748fb5dc 100644 --- a/LEGO1/lego/legoomni/include/legoracers.h +++ b/LEGO1/lego/legoomni/include/legoracers.h @@ -6,9 +6,11 @@ // clang-format on #include "legoracemap.h" -#define LEGORACECAR_UNKNOWN_0 0 -#define LEGORACECAR_UNKNOWN_1 1 +#define LEGORACECAR_NONE 0 +#define LEGORACECAR_NEAR_SKELETON 1 +// kick to the left #define LEGORACECAR_KICK1 2 // name guessed +// kick to the right #define LEGORACECAR_KICK2 4 // name validated by BETA10 0x100cb659 // SIZE 0x08 @@ -23,7 +25,7 @@ struct SkeletonKickPhase { EdgeReference* m_edgeRef; // 0x00 float m_lower; // 0x04 float m_upper; // 0x08 - MxU8 m_userState; // 0x0c + MxU8 m_kickState; // 0x0c }; // VTABLE: LEGO1 0x100d5a08 LegoCarRaceActor @@ -62,10 +64,23 @@ class LegoJetski : public LegoJetskiRaceActor, public LegoRaceMap { void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 // FUNCTION: LEGO1 0x10014150 - MxU32 VTable0x6c(LegoPathBoundary* p_boundary, Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3) - override + MxU32 CheckPresenterAndActorIntersections( + LegoPathBoundary* p_boundary, + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint + ) override { - return LegoJetskiRaceActor::VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3); + return LegoJetskiRaceActor::CheckPresenterAndActorIntersections( + p_boundary, + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint + ); } // vtable+0x6c void Animate(float p_time) override; // vtable+0x70 @@ -78,9 +93,9 @@ class LegoJetski : public LegoJetskiRaceActor, public LegoRaceMap { } // vtable+0x98 // FUNCTION: LEGO1 0x10014210 - MxResult VTable0x9c() override { return LegoJetskiRaceActor::VTable0x9c(); } // vtable+0x9c + MxResult CalculateSpline() override { return LegoJetskiRaceActor::CalculateSpline(); } // vtable+0x9c - virtual void FUN_100136f0(float p_worldSpeed); + virtual void SetMaxLinearVelocity(float p_worldSpeed); static void InitSoundIndices(); @@ -125,10 +140,23 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap { // FUNCTION: LEGO1 0x10014500 // FUNCTION: BETA10 0x100cd5e0 - MxU32 VTable0x6c(LegoPathBoundary* p_boundary, Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3) - override + MxU32 CheckPresenterAndActorIntersections( + LegoPathBoundary* p_boundary, + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint + ) override { - return LegoCarRaceActor::VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3); + return LegoCarRaceActor::CheckPresenterAndActorIntersections( + p_boundary, + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint + ); } // vtable+0x6c void Animate(float p_time) override; // vtable+0x70 @@ -141,7 +169,7 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap { LegoCarRaceActor::SwitchBoundary(p_boundary, p_edge, p_unk0xe4); } // vtable+0x98 - MxResult VTable0x9c() override; // vtable+0x9c + MxResult CalculateSpline() override; // vtable+0x9c virtual void SetMaxLinearVelocity(float p_maxLinearVelocity); virtual void KickCamera(float p_param); @@ -154,7 +182,7 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap { // LegoRaceCar::`scalar deleting destructor' private: - undefined m_userState; // 0x54 + MxU8 m_kickState; // 0x54 float m_kickStart; // 0x58 Mx3DPointFloat m_unk0x5c; // 0x5c diff --git a/LEGO1/lego/legoomni/include/legoracespecial.h b/LEGO1/lego/legoomni/include/legoracespecial.h index fa9dd51d..a6e252b0 100644 --- a/LEGO1/lego/legoomni/include/legoracespecial.h +++ b/LEGO1/lego/legoomni/include/legoracespecial.h @@ -35,21 +35,21 @@ class LegoCarRaceActor : public virtual LegoRaceActor { return !strcmp(p_name, LegoCarRaceActor::ClassName()) || LegoRaceActor::IsA(p_name); } - MxU32 VTable0x6c( + MxU32 CheckPresenterAndActorIntersections( LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint ) override; // vtable+0x6c void Animate(float p_time) override; // vtable+0x70 void SwitchBoundary( LegoPathBoundary*& p_boundary, LegoOrientedEdge*& p_edge, float& p_unk0xe4 - ) override; // vtable+0x98 - MxResult VTable0x9c() override; // vtable+0x9c + ) override; // vtable+0x98 + MxResult CalculateSpline() override; // vtable+0x9c // LegoCarRaceActor vtable @@ -130,13 +130,13 @@ class LegoJetskiRaceActor : public virtual LegoCarRaceActor { return !strcmp(p_name, LegoJetskiRaceActor::ClassName()) || LegoCarRaceActor::IsA(p_name); } - MxU32 VTable0x6c( + MxU32 CheckPresenterAndActorIntersections( LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint ) override; // vtable+0x6c void Animate(float p_time) override; // vtable+0x70 MxS32 VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) override; // vtable+0x1c diff --git a/LEGO1/lego/legoomni/include/legotesttimer.h b/LEGO1/lego/legoomni/include/legotesttimer.h new file mode 100644 index 00000000..51d17d16 --- /dev/null +++ b/LEGO1/lego/legoomni/include/legotesttimer.h @@ -0,0 +1,44 @@ +#ifndef LEGOTESTTIMER_H +#define LEGOTESTTIMER_H + +#include "decomp.h" +#include "misc/legotypes.h" +#include "mxcore.h" +#include "mxparam.h" + +// VTABLE: BETA10 0x101bed08 +// SIZE 0x24 +class LegoTestTimer : public MxCore { +public: + LegoTestTimer(LegoS32 p_numTimers, LegoS32 p_interval, LegoS32 p_numBins, LegoS32 p_type); + ~LegoTestTimer() override; // vtable+00 + MxLong Notify(MxParam& p_param) override; // vtable+04 + + // FUNCTION: BETA10 0x100d18e0 + static const char* HandlerClassName() { return "LegoTestTimer"; } + + // FUNCTION: BETA10 0x100d18b0 + const char* ClassName() const override // vtable+0c + { + return HandlerClassName(); + } + + void Tick(LegoS32 p_timer); + void ResetAtNextTick(); + void Print(); + + // SYNTHETIC: BETA10 0x100d1900 + // LegoTestTimer::`scalar deleting destructor' + +private: + LegoS32** m_timers; // 0x08 + LegoS32* m_lastTime; // 0x0c + LegoS32* m_totalTime; // 0x10 + LegoS32 m_numTimers; // 0x14 + LegoS32 m_numBins; // 0x18 + LegoS32 m_interval; // 0x1c + MxBool m_enable; // 0x20 + MxBool m_keyRegistered; // 0x21 +}; + +#endif // LEGOTESTTIMER_H diff --git a/LEGO1/lego/legoomni/include/legoworldpresenter.h b/LEGO1/lego/legoomni/include/legoworldpresenter.h index 88848873..46dc4721 100644 --- a/LEGO1/lego/legoomni/include/legoworldpresenter.h +++ b/LEGO1/lego/legoomni/include/legoworldpresenter.h @@ -43,7 +43,7 @@ class LegoWorldPresenter : public LegoEntityPresenter { void StartingTickle() override; // vtable+0x1c void ParseExtra() override; // vtable+0x30 MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c - void VTable0x60(MxPresenter* p_presenter) override; // vtable+0x60 + void AdvanceSerialAction(MxPresenter* p_presenter) override; // vtable+0x60 MxResult LoadWorld(char* p_worldName, LegoWorld* p_world); diff --git a/LEGO1/lego/legoomni/include/mxcompositemediapresenter.h b/LEGO1/lego/legoomni/include/mxcompositemediapresenter.h index 3ccc12d7..3bf92848 100644 --- a/LEGO1/lego/legoomni/include/mxcompositemediapresenter.h +++ b/LEGO1/lego/legoomni/include/mxcompositemediapresenter.h @@ -32,8 +32,8 @@ class MxCompositeMediaPresenter : public MxCompositePresenter { MxResult PutData() override; // vtable+0x4c private: - MxS16 m_unk0x4c; // 0x4c - MxBool m_unk0x4e; // 0x4e + MxS16 m_remainingChildren; // 0x4c + MxBool m_allChildrenStreaming; // 0x4e }; // SYNTHETIC: LEGO1 0x10074000 diff --git a/LEGO1/lego/legoomni/include/mxcontrolpresenter.h b/LEGO1/lego/legoomni/include/mxcontrolpresenter.h index d3d2a96a..8e37b186 100644 --- a/LEGO1/lego/legoomni/include/mxcontrolpresenter.h +++ b/LEGO1/lego/legoomni/include/mxcontrolpresenter.h @@ -18,7 +18,7 @@ class MxControlPresenter : public MxCompositePresenter { void RepeatingTickle() override {} // vtable+0x24 // FUNCTION: LEGO1 0x10043fe0 - MxBool VTable0x64(undefined4 p_undefined) override { return m_unk0x50; } // vtable+0x64 + MxBool GetActionEnded(undefined4 p_undefined) override { return m_unk0x50; } // vtable+0x64 // FUNCTION: LEGO1 0x10043ff0 virtual void VTable0x68(MxBool p_unk0x50) { m_unk0x50 = p_unk0x50; } // vtable+0x68 diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index 9c38f7a8..5af883d4 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -179,9 +179,9 @@ MxResult Act2Actor::HitActor(LegoPathActor*, MxBool) } // FUNCTION: LEGO1 0x10018a20 -MxResult Act2Actor::VTable0x9c() +MxResult Act2Actor::CalculateSpline() { - if (m_grec && !m_grec->GetBit1()) { + if (m_grec && !m_grec->HasPath()) { delete m_grec; m_grec = NULL; return SUCCESS; @@ -198,7 +198,7 @@ MxResult Act2Actor::VTable0x9c() brickstrROI->UpdateTransformationRelativeToParent(brickstrMatrix); } - return LegoPathActor::VTable0x9c(); + return LegoPathActor::CalculateSpline(); } } @@ -410,7 +410,7 @@ void Act2Actor::FindPath(MxU32 p_location) newDirection = g_brickstrLocations[p_location].m_direction; LegoPathBoundary* newBoundary = m_pathController->GetPathBoundary(g_brickstrLocations[p_location].m_boundary); - MxResult sts = m_pathController->FUN_10048310( + MxResult sts = m_pathController->FindPath( m_grec, m_roi->GetWorldPosition(), m_roi->GetWorldDirection(), @@ -607,7 +607,7 @@ MxU32 Act2Actor::UpdateShot(MxFloat p_time) return FALSE; } - m_lastTime = p_time; + m_transformTime = p_time; LegoROI* brickstrROI = FindROI("brickstr"); MxMatrix initialTransform = m_roi->GetLocal2World(); diff --git a/LEGO1/lego/legoomni/src/actors/act3actors.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp index 0b04b09a..bb533004 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actors.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -101,20 +101,20 @@ Act3Actor::Act3Actor() // FUNCTION: LEGO1 0x1003fb70 // FUNCTION: BETA10 0x100180ab -MxU32 Act3Actor::VTable0x90(float p_time, Matrix4& p_transform) +MxU32 Act3Actor::StepState(float p_time, Matrix4& p_transform) { - // Note: Code duplication with LegoExtraActor::VTable0x90 + // Note: Code duplication with LegoExtraActor::StepState switch (m_actorState & c_maxState) { case c_initial: - case c_one: + case c_ready: return TRUE; - case c_two: + case c_hit: m_unk0x1c = p_time + 2000.0f; - m_actorState = c_three; - m_actorTime += (p_time - m_lastTime) * m_worldSpeed; - m_lastTime = p_time; + m_actorState = c_hitAnimation; + m_actorTime += (p_time - m_transformTime) * m_worldSpeed; + m_transformTime = p_time; return FALSE; - case c_three: + case c_hitAnimation: assert(!m_userNavFlag); Vector3 positionRef(p_transform[3]); @@ -128,10 +128,10 @@ MxU32 Act3Actor::VTable0x90(float p_time, Matrix4& p_transform) p_transform.RotateX(0.6); positionRef = position; - m_actorTime += (p_time - m_lastTime) * m_worldSpeed; - m_lastTime = p_time; + m_actorTime += (p_time - m_transformTime) * m_worldSpeed; + m_transformTime = p_time; - VTable0x74(p_transform); + ApplyTransform(p_transform); return FALSE; } else { @@ -167,7 +167,7 @@ MxResult Act3Actor::HitActor(LegoPathActor* p_actor, MxBool p_bool) roi->SetLocal2World(local2world); roi->WrappedUpdateWorldData(); - p_actor->SetActorState(c_two | c_noCollide); + p_actor->SetActorState(c_hit | c_noCollide); } return SUCCESS; @@ -196,7 +196,7 @@ MxResult Act3Cop::HitActor(LegoPathActor* p_actor, MxBool p_bool) assert(m_world); ((Act3*) m_world)->EatDonut(index); - m_unk0x20 = m_lastTime + 2000; + m_unk0x20 = m_transformTime + 2000; SetWorldSpeed(6.0); assert(SoundManager()->GetCacheSoundManager()); @@ -285,7 +285,7 @@ void Act3Cop::Animate(float p_time) { Act3Actor::Animate(p_time); - if (m_unk0x20 > 0.0f && m_unk0x20 < m_lastTime) { + if (m_unk0x20 > 0.0f && m_unk0x20 < m_transformTime) { SetWorldSpeed(2.0f); m_unk0x20 = -1.0f; } @@ -329,7 +329,7 @@ MxResult Act3Cop::FUN_10040360() LegoPathEdgeContainer* grec = NULL; Act3* a3 = (Act3*) m_world; - MxMatrix local74(m_unk0xec); + MxMatrix local74(m_local2World); Vector3 local2c(local74[3]); Vector3 local20(local74[2]); @@ -346,7 +346,7 @@ MxResult Act3Cop::FUN_10040360() assert(grec); MxFloat local34; - if (m_pathController->FUN_10048310( + if (m_pathController->FindPath( grec, local2c, local20, @@ -384,7 +384,7 @@ MxResult Act3Cop::FUN_10040360() MxFloat locald8; LegoPathEdgeContainer *local138, *local134, *local140, *local13c; // unused - if (m_pathController->FUN_10048310( + if (m_pathController->FindPath( r2, local2c, local20, @@ -424,7 +424,7 @@ MxResult Act3Cop::FUN_10040360() MxFloat local100; LegoPathEdgeContainer *local150, *local14c; // unused - if (m_pathController->FUN_10048310( + if (m_pathController->FindPath( grec, local2c, local20, @@ -457,7 +457,7 @@ MxResult Act3Cop::FUN_10040360() vecUnk = m_grec->m_position; m_boundary = m_grec->m_boundary; - m_grec->m_direction = m_unk0xec[3]; + m_grec->m_direction = m_local2World[3]; m_grec->m_direction -= vecUnk; } else { @@ -470,7 +470,7 @@ MxResult Act3Cop::FUN_10040360() local128 = *v2; local128 -= *v1; - local128 *= m_unk0xe4; + local128 *= m_destScale; local128 += *v1; local128 *= -1.0f; local128 += m_grec->m_position; @@ -485,14 +485,14 @@ MxResult Act3Cop::FUN_10040360() vecUnk = *v2; vecUnk -= *v1; - vecUnk *= m_unk0xe4; + vecUnk *= m_destScale; vecUnk += *v1; } - Vector3 v1(m_unk0xec[0]); - Vector3 v2(m_unk0xec[1]); - Vector3 v3(m_unk0xec[2]); - Vector3 v4(m_unk0xec[3]); + Vector3 v1(m_local2World[0]); + Vector3 v2(m_local2World[1]); + Vector3 v3(m_local2World[2]); + Vector3 v4(m_local2World[3]); v3 = v4; v3 -= vecUnk; @@ -501,7 +501,7 @@ MxResult Act3Cop::FUN_10040360() v1.Unitize(); v2.EqualsCross(v3, v1); - VTable0x9c(); + CalculateSpline(); } return SUCCESS; @@ -509,17 +509,17 @@ MxResult Act3Cop::FUN_10040360() // FUNCTION: LEGO1 0x10040d20 // FUNCTION: BETA10 0x1001942c -MxResult Act3Cop::VTable0x9c() +MxResult Act3Cop::CalculateSpline() { - if (m_grec && !m_grec->GetBit1()) { + if (m_grec && !m_grec->HasPath()) { delete m_grec; m_grec = NULL; - m_lastTime = Timer()->GetTime(); + m_transformTime = Timer()->GetTime(); FUN_10040360(); return SUCCESS; } - return Act3Actor::VTable0x9c(); + return Act3Actor::CalculateSpline(); } // FUNCTION: LEGO1 0x10040e10 @@ -571,7 +571,7 @@ void Act3Brickster::ParseAction(char* p_extra) // FUNCTION: BETA10 0x100197d7 void Act3Brickster::Animate(float p_time) { - if (m_lastTime <= m_unk0x20 && m_unk0x20 <= p_time) { + if (m_transformTime <= m_unk0x20 && m_unk0x20 <= p_time) { SetWorldSpeed(5.0f); } @@ -619,7 +619,7 @@ void Act3Brickster::Animate(float p_time) } else { MxMatrix local70; - local70 = m_unk0xec; + local70 = m_local2World; Vector3 local14(local70[0]); Vector3 local28(local70[1]); @@ -643,7 +643,7 @@ void Act3Brickster::Animate(float p_time) } } - m_lastTime = p_time; + m_transformTime = p_time; break; case 4: assert(m_shootAnim && m_bInfo); @@ -664,7 +664,7 @@ void Act3Brickster::Animate(float p_time) } else { MxMatrix locale4; - locale4 = m_unk0xec; + locale4 = m_local2World; Vector3 local88(locale4[0]); Vector3 local9c(locale4[1]); @@ -690,7 +690,7 @@ void Act3Brickster::Animate(float p_time) } } - m_lastTime = p_time; + m_transformTime = p_time; break; case 5: if (m_grec == NULL) { @@ -794,11 +794,11 @@ MxResult Act3Brickster::FUN_100417c0() LegoPathEdgeContainer* grec = NULL; Act3* a3 = (Act3*) m_world; - MxMatrix local70(m_unk0xec); + MxMatrix local70(m_local2World); Vector3 local28(local70[3]); Vector3 local20(local70[2]); - if (m_unk0x58 < 8 && m_unk0x24 + 5000.0f < m_lastTime) { + if (m_unk0x58 < 8 && m_unk0x24 + 5000.0f < m_transformTime) { float local18; for (MxS32 i = 0; i < MAX_PIZZAS; i++) { @@ -824,7 +824,7 @@ MxResult Act3Brickster::FUN_100417c0() MxFloat locald8; LegoPathEdgeContainer *local16c, *local168, *local174, *local170; // unused - if (m_pathController->FUN_10048310( + if (m_pathController->FindPath( r2, local28, local20, @@ -908,7 +908,7 @@ MxResult Act3Brickster::FUN_100417c0() MxFloat local13c; LegoPathEdgeContainer *local1c0, *local1bc; // unused - if (m_pathController->FUN_10048310( + if (m_pathController->FindPath( grec, local28, local20, @@ -951,7 +951,7 @@ MxResult Act3Brickster::FUN_100417c0() vecUnk = m_grec->m_position; m_boundary = m_grec->m_boundary; - m_grec->m_direction = m_unk0xec[3]; + m_grec->m_direction = m_local2World[3]; m_grec->m_direction -= vecUnk; local150 = m_grec->m_direction; @@ -965,7 +965,7 @@ MxResult Act3Brickster::FUN_100417c0() local150 = *v2; local150 -= *v1; - local150 *= m_unk0xe4; + local150 *= m_destScale; local150 += *v1; local150 *= -1.0f; local150 += m_grec->m_position; @@ -980,14 +980,14 @@ MxResult Act3Brickster::FUN_100417c0() vecUnk = *v2; vecUnk -= *v1; - vecUnk *= m_unk0xe4; + vecUnk *= m_destScale; vecUnk += *v1; } - Vector3 v1(m_unk0xec[0]); - Vector3 v2(m_unk0xec[1]); - Vector3 v3(m_unk0xec[2]); - Vector3 v4(m_unk0xec[3]); + Vector3 v1(m_local2World[0]); + Vector3 v2(m_local2World[1]); + Vector3 v3(m_local2World[2]); + Vector3 v4(m_local2World[3]); v3 = v4; v3 -= vecUnk; @@ -996,7 +996,7 @@ MxResult Act3Brickster::FUN_100417c0() v1.Unitize(); v2.EqualsCross(v3, v1); - VTable0x9c(); + CalculateSpline(); if (m_pInfo != NULL) { m_unk0x38 = 5; @@ -1099,10 +1099,10 @@ MxS32 Act3Brickster::FUN_10042300() m_destEdge = maxE; if (m_boundary != boundaries[0]) { - m_unk0xe4 = 1.0 - m_unk0xe4; + m_destScale = 1.0 - m_destScale; } - VTable0x9c(); + CalculateSpline(); } return -1; @@ -1119,16 +1119,16 @@ void Act3Brickster::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoOrientedEd // FUNCTION: LEGO1 0x100429d0 // FUNCTION: BETA10 0x1001b75b -MxResult Act3Brickster::VTable0x9c() +MxResult Act3Brickster::CalculateSpline() { - if (m_grec && !m_grec->GetBit1()) { + if (m_grec && !m_grec->HasPath()) { delete m_grec; m_grec = NULL; - m_lastTime = Timer()->GetTime(); + m_transformTime = Timer()->GetTime(); return SUCCESS; } - return Act3Actor::VTable0x9c(); + return Act3Actor::CalculateSpline(); } // FUNCTION: LEGO1 0x10042ab0 @@ -1217,7 +1217,7 @@ void Act3Shark::ParseAction(char* p_extra) token = strtok(NULL, g_parseExtraTokens); if (token != NULL) { - presenter->FUN_1006d680(this, atof(token)); + presenter->CreateROIAndBuildMap(this, atof(token)); } } diff --git a/LEGO1/lego/legoomni/src/actors/act3ammo.cpp b/LEGO1/lego/legoomni/src/actors/act3ammo.cpp index 21731bee..8630fb8b 100644 --- a/LEGO1/lego/legoomni/src/actors/act3ammo.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3ammo.cpp @@ -17,7 +17,7 @@ DECOMP_SIZE_ASSERT(Act3Ammo, 0x1a0) // Initialized at LEGO1 0x100537c0 // GLOBAL: LEGO1 0x10104f08 -Mx3DPointFloat Act3Ammo::g_unk0x10104f08 = Mx3DPointFloat(0.0, 5.0, 0.0); +Mx3DPointFloat Act3Ammo::g_hitTranslation = Mx3DPointFloat(0.0, 5.0, 0.0); // FUNCTION: LEGO1 0x100537f0 // FUNCTION: BETA10 0x1001d648 @@ -111,43 +111,44 @@ MxResult Act3Ammo::Create(Act3* p_world, MxU32 p_isPizza, MxS32 p_index) // FUNCTION: LEGO1 0x10053b40 // FUNCTION: BETA10 0x1001db2a -MxResult Act3Ammo::FUN_10053b40(const Vector3& p_srcLoc, const Vector3& p_srcDir, const Vector3& p_srcUp) +MxResult Act3Ammo::CalculateArc(const Vector3& p_srcLoc, const Vector3& p_srcDir, const Vector3& p_srcUp) { assert(p_srcDir[1] != 0); - MxFloat local1c = -(p_srcLoc[1] / p_srcDir[1]); - Mx3DPointFloat local18(p_srcDir); - Mx3DPointFloat local34; + MxFloat yRatioLocDir = -(p_srcLoc[1] / p_srcDir[1]); + Mx3DPointFloat groundPoint(p_srcDir); + Mx3DPointFloat negNormalUp; - local18 *= local1c; - local18 += p_srcLoc; + groundPoint *= yRatioLocDir; + groundPoint += p_srcLoc; - local34[0] = local34[2] = 0.0f; - local34[1] = -1.0f; + negNormalUp[0] = negNormalUp[2] = 0.0f; + negNormalUp[1] = -1.0f; - m_eq[1] = p_srcUp; - m_eq[2] = p_srcLoc; + m_coefficients[1] = p_srcUp; + m_coefficients[2] = p_srcLoc; - Mx3DPointFloat local48(local34); - local48 -= m_eq[1]; + Mx3DPointFloat upRelative(negNormalUp); + upRelative -= m_coefficients[1]; for (MxS32 i = 0; i < 3; i++) { - if (local18[0] == p_srcLoc[0]) { + if (groundPoint[0] == p_srcLoc[0]) { return FAILURE; } - m_eq[0][i] = (local48[i] * local48[i] + local48[i] * m_eq[1][i] * 2.0f) / ((local18[i] - p_srcLoc[i]) * 4.0f); + m_coefficients[0][i] = (upRelative[i] * upRelative[i] + upRelative[i] * m_coefficients[1][i] * 2.0f) / + ((groundPoint[i] - p_srcLoc[i]) * 4.0f); } - assert(m_eq[0][0] > 0.000001 || m_eq[0][0] < -0.000001); + assert(m_coefficients[0][0] > 0.000001 || m_coefficients[0][0] < -0.000001); - m_unk0x19c = local48[0] / (m_eq[0][0] * 2.0f); + m_apexParameter = upRelative[0] / (m_coefficients[0][0] * 2.0f); return SUCCESS; } // FUNCTION: LEGO1 0x10053cb0 // FUNCTION: BETA10 0x1001ddf4 -MxResult Act3Ammo::FUN_10053cb0(LegoPathController* p_p, LegoPathBoundary* p_boundary, MxFloat p_unk0x19c) +MxResult Act3Ammo::Shoot(LegoPathController* p_p, LegoPathBoundary* p_boundary, MxFloat p_apexParameter) { assert(p_p); assert(IsValid()); @@ -164,21 +165,21 @@ MxResult Act3Ammo::FUN_10053cb0(LegoPathController* p_p, LegoPathBoundary* p_bou m_pathController = p_p; m_boundary = p_boundary; m_BADuration = 10000.0f; - m_unk0x19c = p_unk0x19c; - m_unk0x7c = 0.0f; - m_lastTime = -1.0f; - m_actorState = c_one; + m_apexParameter = p_apexParameter; + m_traveledDistance = 0.0f; + m_transformTime = -1.0f; + m_actorState = c_ready; return SUCCESS; } // FUNCTION: LEGO1 0x10053d30 // FUNCTION: BETA10 0x1001df73 -MxResult Act3Ammo::FUN_10053d30(LegoPathController* p_p, MxFloat p_unk0x19c) +MxResult Act3Ammo::Shoot(LegoPathController* p_p, MxFloat p_apexParameter) { assert(p_p); assert(IsValid()); - SetBit4(TRUE); + SetShootWithoutBoundary(TRUE); if (IsPizza()) { assert(SoundManager()->GetCacheSoundManager()); @@ -191,58 +192,58 @@ MxResult Act3Ammo::FUN_10053d30(LegoPathController* p_p, MxFloat p_unk0x19c) m_pathController = p_p; m_BADuration = 10000.0f; - m_unk0x19c = p_unk0x19c; - m_unk0x7c = 0.0f; - m_lastTime = -1.0f; - m_actorState = c_one; + m_apexParameter = p_apexParameter; + m_traveledDistance = 0.0f; + m_transformTime = -1.0f; + m_actorState = c_ready; return SUCCESS; } // FUNCTION: LEGO1 0x10053db0 // FUNCTION: BETA10 0x1001e0f0 -MxResult Act3Ammo::FUN_10053db0(float p_param1, Matrix4& p_param2) +MxResult Act3Ammo::CalculateTransformOnCurve(float p_curveParameter, Matrix4& p_transform) { - float local34 = p_param1 * p_param1; + float curveParameterSquare = p_curveParameter * p_curveParameter; - Vector3 local14(p_param2[0]); - Vector3 local3c(p_param2[1]); - Vector3 localc(p_param2[2]); - Vector3 local30(p_param2[3]); - Mx3DPointFloat local28; + Vector3 right(p_transform[0]); + Vector3 up(p_transform[1]); + Vector3 dir(p_transform[2]); + Vector3 pos(p_transform[3]); + Mx3DPointFloat sndCoeff; - local28 = m_eq[1]; - local28 *= p_param1; - local30 = m_eq[0]; - local30 *= local34; - local30 += local28; - local30 += m_eq[2]; - localc = m_eq[0]; - localc *= 2.0f; - localc *= p_param1; - localc += m_eq[1]; - localc *= -1.0f; + sndCoeff = m_coefficients[1]; + sndCoeff *= p_curveParameter; + pos = m_coefficients[0]; + pos *= curveParameterSquare; + pos += sndCoeff; + pos += m_coefficients[2]; + dir = m_coefficients[0]; + dir *= 2.0f; + dir *= p_curveParameter; + dir += m_coefficients[1]; + dir *= -1.0f; - if (localc.Unitize() != 0) { + if (dir.Unitize() != 0) { assert(0); return FAILURE; } - local14[1] = local14[2] = 0.0f; - local14[0] = 1.0f; - local3c.EqualsCross(localc, local14); + right[1] = right[2] = 0.0f; + right[0] = 1.0f; + up.EqualsCross(dir, right); - if (local3c.Unitize() != 0) { - local14[0] = local14[1] = 0.0f; - local14[2] = 1.0f; - local3c.EqualsCross(localc, local14); + if (up.Unitize() != 0) { + right[0] = right[1] = 0.0f; + right[2] = 1.0f; + up.EqualsCross(dir, right); - if (local3c.Unitize() != 0) { + if (up.Unitize() != 0) { assert(0); return FAILURE; } } - local14.EqualsCross(local3c, localc); + right.EqualsCross(up, dir); return SUCCESS; } @@ -254,19 +255,19 @@ void Act3Ammo::Animate(float p_time) switch (m_actorState & c_maxState) { case c_initial: - case c_one: + case c_ready: break; - case c_two: - m_unk0x158 = p_time + 2000.0f; - m_actorState = c_three; + case c_hit: + m_rotateTimeout = p_time + 2000.0f; + m_actorState = c_hitAnimation; return; - case c_three: + case c_hitAnimation: MxMatrix transform; Vector3 positionRef(transform[3]); transform = m_roi->GetLocal2World(); - if (m_unk0x158 > p_time) { + if (m_rotateTimeout > p_time) { Mx3DPointFloat position; position = positionRef; @@ -279,9 +280,9 @@ void Act3Ammo::Animate(float p_time) } else { m_actorState = c_initial; - m_unk0x158 = 0; + m_rotateTimeout = 0; - positionRef -= g_unk0x10104f08; + positionRef -= g_hitTranslation; m_roi->SetLocal2World(transform); m_roi->WrappedUpdateWorldData(); return; @@ -292,90 +293,90 @@ void Act3Ammo::Animate(float p_time) return; } - if (m_lastTime < 0.0f) { - m_lastTime = p_time; - m_unk0x7c = 0.0f; + if (m_transformTime < 0.0f) { + m_transformTime = p_time; + m_traveledDistance = 0.0f; } - MxMatrix local104; - MxMatrix local60; + MxMatrix transform; + MxMatrix additionalTransform; - float f = (m_BADuration - m_unk0x7c) / m_worldSpeed + m_lastTime; + float f = (m_BADuration - m_traveledDistance) / m_worldSpeed + m_transformTime; - undefined4 localb4 = 0; - undefined4 localbc = 0; - MxU32 local14 = FALSE; - MxU32 localb8 = FALSE; + undefined4 unused1 = 0; + undefined4 unused2 = 0; + MxU32 annihilated = FALSE; + MxU32 reachedTarget = FALSE; if (f > p_time) { - m_actorTime = (p_time - m_lastTime) * m_worldSpeed + m_actorTime; - m_unk0x7c = (p_time - m_lastTime) * m_worldSpeed + m_unk0x7c; - m_lastTime = p_time; + m_actorTime = (p_time - m_transformTime) * m_worldSpeed + m_actorTime; + m_traveledDistance = (p_time - m_transformTime) * m_worldSpeed + m_traveledDistance; + m_transformTime = p_time; } else { - localb8 = TRUE; - m_unk0x7c = m_BADuration; - m_lastTime = p_time; + reachedTarget = TRUE; + m_traveledDistance = m_BADuration; + m_transformTime = p_time; } - local104.SetIdentity(); + transform.SetIdentity(); - MxResult r = FUN_10053db0((m_unk0x7c / m_BADuration) * m_unk0x19c, local104); + MxResult r = CalculateTransformOnCurve((m_traveledDistance / m_BADuration) * m_apexParameter, transform); assert(r == 0); // SUCCESS - local60.SetIdentity(); + additionalTransform.SetIdentity(); if (IsPizza()) { - local60.Scale(2.0f, 2.0f, 2.0f); + additionalTransform.Scale(2.0f, 2.0f, 2.0f); } else { - local60.Scale(5.0f, 5.0f, 5.0f); + additionalTransform.Scale(5.0f, 5.0f, 5.0f); } - if (localb8) { + if (reachedTarget) { if (m_boundary != NULL) { - Vector3 local17c(local104[0]); - Vector3 local184(local104[1]); - Vector3 local174(local104[2]); + Vector3 right(transform[0]); + Vector3 up(transform[1]); + Vector3 dir(transform[2]); if (IsPizza()) { - local184 = *m_boundary->GetUp(); - local17c[0] = 1.0f; - local17c[1] = local17c[2] = 0.0f; - local174.EqualsCross(local17c, local184); - local174.Unitize(); - local17c.EqualsCross(local184, local174); + up = *m_boundary->GetUp(); + right[0] = 1.0f; + right[1] = right[2] = 0.0f; + dir.EqualsCross(right, up); + dir.Unitize(); + right.EqualsCross(up, dir); } else { - local17c = *m_boundary->GetUp(); - local184[0] = 1.0f; - local184[1] = local184[2] = 0.0f; - local174.EqualsCross(local17c, local184); - local174.Unitize(); - local184.EqualsCross(local174, local17c); + right = *m_boundary->GetUp(); + up[0] = 1.0f; + up[1] = up[2] = 0.0f; + dir.EqualsCross(right, up); + dir.Unitize(); + up.EqualsCross(dir, right); } } m_actorState = c_initial; } else { - local60.RotateX(m_actorTime / 10.0f); - local60.RotateY(m_actorTime / 6.0f); + additionalTransform.RotateX(m_actorTime / 10.0f); + additionalTransform.RotateY(m_actorTime / 6.0f); } - MxMatrix localb0(local104); - local104.Product(local60, localb0); - m_roi->SetLocal2World(local104); + MxMatrix transformCopy(transform); + transform.Product(additionalTransform, transformCopy); + m_roi->SetLocal2World(transform); m_roi->WrappedUpdateWorldData(); - if (m_BADuration <= m_unk0x7c) { + if (m_BADuration <= m_traveledDistance) { m_worldSpeed = 0.0f; } - Vector3 local68(local104[3]); + Vector3 position(transform[3]); - if (localb8) { - if (IsBit4()) { + if (reachedTarget) { + if (IsShootWithoutBoundary()) { if (IsPizza()) { m_world->RemovePizza(*this); m_world->TriggerHitSound(2); @@ -414,16 +415,16 @@ void Act3Ammo::Animate(float p_time) assert(r); if (!strncmp(r->GetName(), "pammo", 5)) { - Mx3DPointFloat local1c8; - Mx3DPointFloat local1b4; + Mx3DPointFloat otherPosition; + Mx3DPointFloat distance; - local1c8 = r->GetLocal2World()[3]; - local1b4 = m_roi->GetLocal2World()[3]; + otherPosition = r->GetLocal2World()[3]; + distance = m_roi->GetLocal2World()[3]; - local1b4 -= local1c8; + distance -= otherPosition; float radius = r->GetWorldBoundingSphere().Radius(); - if (local1b4.LenSquared() <= radius * radius) { + if (distance.LenSquared() <= radius * radius) { MxS32 index = -1; if (sscanf(r->GetName(), "pammo%d", &index) != 1) { assert(0); @@ -444,22 +445,22 @@ void Act3Ammo::Animate(float p_time) assert(SoundManager()->GetCacheSoundManager()); SoundManager()->GetCacheSoundManager()->Play("dnhitpz", NULL, FALSE); m_world->RemoveDonut(*this); - local14 = TRUE; + annihilated = TRUE; break; } } } else if (!strncmp(r->GetName(), "dammo", 5)) { - Mx3DPointFloat local1f8; - Mx3DPointFloat local1e4; + Mx3DPointFloat otherPosition; + Mx3DPointFloat distance; - local1f8 = r->GetLocal2World()[3]; - local1e4 = m_roi->GetLocal2World()[3]; + otherPosition = r->GetLocal2World()[3]; + distance = m_roi->GetLocal2World()[3]; - local1e4 -= local1f8; + distance -= otherPosition; float radius = r->GetWorldBoundingSphere().Radius(); - if (local1e4.LenSquared() <= radius * radius) { + if (distance.LenSquared() <= radius * radius) { MxS32 index = -1; if (sscanf(r->GetName(), "dammo%d", &index) != 1) { assert(0); @@ -473,19 +474,19 @@ void Act3Ammo::Animate(float p_time) assert(SoundManager()->GetCacheSoundManager()); SoundManager()->GetCacheSoundManager()->Play("pzhitdn", NULL, FALSE); m_world->RemovePizza(*this); - local14 = TRUE; + annihilated = TRUE; break; } } } } - if (!local14) { + if (!annihilated) { if (IsPizza()) { - m_world->FUN_10073360(*this, local68); + m_world->FUN_10073360(*this, position); } else { - m_world->FUN_10073390(*this, local68); + m_world->FUN_10073390(*this, position); } m_worldSpeed = -1.0f; diff --git a/LEGO1/lego/legoomni/src/actors/bike.cpp b/LEGO1/lego/legoomni/src/actors/bike.cpp index 2924a2bd..e3414254 100644 --- a/LEGO1/lego/legoomni/src/actors/bike.cpp +++ b/LEGO1/lego/legoomni/src/actors/bike.cpp @@ -19,8 +19,8 @@ DECOMP_SIZE_ASSERT(Bike, 0x164) Bike::Bike() { m_maxLinearVel = 20.0; - m_unk0x150 = 3.0; - m_unk0x148 = 1; + m_linearRotationRatio = 3.0; + m_canRotate = 1; } // FUNCTION: LEGO1 0x100768f0 diff --git a/LEGO1/lego/legoomni/src/actors/doors.cpp b/LEGO1/lego/legoomni/src/actors/doors.cpp index 0a935334..49ca3766 100644 --- a/LEGO1/lego/legoomni/src/actors/doors.cpp +++ b/LEGO1/lego/legoomni/src/actors/doors.cpp @@ -13,15 +13,15 @@ DECOMP_SIZE_ASSERT(Doors, 0x1f8) // GLOBAL: LEGO1 0x100d8e7c // GLOBAL: BETA10 0x101b954c -MxFloat g_unk0x100d8e7c = 1000.0f; +MxFloat g_timeMoving = 1000.0f; // GLOBAL: LEGO1 0x100d8e80 // GLOBAL: BETA10 0x101b9550 -MxFloat g_unk0x100d8e80 = 4000.0f; +MxFloat g_timeOpened = 4000.0f; // GLOBAL: LEGO1 0x100d8e84 // GLOBAL: BETA10 0x101b9554 -MxFloat g_unk0x100d8e84 = 6000.0f; +MxFloat g_totalTime = 6000.0f; // = g_timeMoving + g_totalTime + g_timeMoving // FUNCTION: LEGO1 0x10066100 // FUNCTION: BETA10 0x10026850 @@ -29,36 +29,36 @@ MxResult Doors::HitActor(LegoPathActor* p_actor, MxBool p_bool) { assert(m_ltDoor && m_rtDoor); - if (m_unk0x154 == 1) { - m_unk0x154 = 2; - m_unk0x158 = Timer()->GetTime(); - m_ltDoorLocal = m_ltDoor->GetLocal2World(); - m_rtDoorLocal = m_rtDoor->GetLocal2World(); + if (m_state == e_closed) { + m_state = e_cycling; + m_hitTime = Timer()->GetTime(); + m_ltDoorOriginalLocal = m_ltDoor->GetLocal2World(); + m_rtDoorOriginalLocal = m_rtDoor->GetLocal2World(); } - return m_unk0x1f4 < 0.001 ? SUCCESS : FAILURE; + return m_angle < 0.001 ? SUCCESS : FAILURE; } // FUNCTION: LEGO1 0x10066190 // FUNCTION: BETA10 0x1002696b -MxFloat Doors::VTable0xcc(float p_time) +MxFloat Doors::CalculateAngle(float p_time) { - MxFloat fVar1; + MxFloat timeSinceHit; - fVar1 = p_time - m_unk0x158; + timeSinceHit = p_time - m_hitTime; - if (fVar1 <= 0.0f) { + if (timeSinceHit <= 0.0f) { return 0.0f; } - if (fVar1 <= g_unk0x100d8e7c) { - return fVar1 * 1.570796 / g_unk0x100d8e7c; + if (timeSinceHit <= g_timeMoving) { + return timeSinceHit * 1.570796 / g_timeMoving; } - else if (fVar1 <= g_unk0x100d8e7c + g_unk0x100d8e80) { + else if (timeSinceHit <= g_timeMoving + g_timeOpened) { return 1.570796012878418; // Pi / 2 } - else if (fVar1 <= g_unk0x100d8e84) { - return (1.0 - ((fVar1 - g_unk0x100d8e80) - g_unk0x100d8e7c) / g_unk0x100d8e7c) * 1.570796; + else if (timeSinceHit <= g_totalTime) { + return (1.0 - ((timeSinceHit - g_timeOpened) - g_timeMoving) / g_timeMoving) * 1.570796; } return 0.0f; @@ -71,46 +71,46 @@ void Doors::Animate(float p_time) assert(m_ltDoor && m_rtDoor); // TODO: Match - m_roi->SetVisibility(m_boundary->GetFlag0x10()); + m_roi->SetVisibility(m_boundary->GetVisibility()); - switch (m_unk0x154) { - case 0: - m_unk0x154 = 1; + switch (m_state) { + case e_none: + m_state = e_closed; m_actorState = c_initial; break; - case 1: + case e_closed: break; - case 2: - float local8 = VTable0xcc(p_time); + case e_cycling: + float angle = CalculateAngle(p_time); - if (local8 > 0.0f) { - MxMatrix local58(m_ltDoorLocal); - Vector3 local10(local58[3]); + if (angle > 0.0f) { + MxMatrix transform(m_ltDoorOriginalLocal); + Vector3 position(transform[3]); - local10.Clear(); - local58.RotateY(-local8); - local10 = m_ltDoorLocal[3]; - m_ltDoor->SetLocal2World(local58); + position.Clear(); + transform.RotateY(-angle); + position = m_ltDoorOriginalLocal[3]; + m_ltDoor->SetLocal2World(transform); m_ltDoor->WrappedUpdateWorldData(); - local58 = m_rtDoorLocal; - local10.Clear(); - local58.RotateY(local8); - local10 = m_rtDoorLocal[3]; - m_rtDoor->SetLocal2World(local58); + transform = m_rtDoorOriginalLocal; + position.Clear(); + transform.RotateY(angle); + position = m_rtDoorOriginalLocal[3]; + m_rtDoor->SetLocal2World(transform); m_rtDoor->WrappedUpdateWorldData(); - m_unk0x1f4 = local8; + m_angle = angle; } - if (m_unk0x158 + g_unk0x100d8e84 < p_time) { - m_ltDoor->SetLocal2World(m_ltDoorLocal); - m_rtDoor->SetLocal2World(m_rtDoorLocal); + if (m_hitTime + g_totalTime < p_time) { + m_ltDoor->SetLocal2World(m_ltDoorOriginalLocal); + m_rtDoor->SetLocal2World(m_rtDoorOriginalLocal); m_ltDoor->WrappedUpdateWorldData(); m_rtDoor->WrappedUpdateWorldData(); - m_unk0x154 = 1; + m_state = e_closed; m_actorState = c_initial; - m_unk0x1f4 = 0; + m_angle = 0; } } } diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 0337e96a..a69430eb 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -384,7 +384,7 @@ MxLong Helicopter::HandleEndAnim(LegoEndAnimNotificationParam& p_param) } // FUNCTION: LEGO1 0x10003e90 -void Helicopter::VTable0x74(Matrix4& p_transform) +void Helicopter::ApplyTransform(Matrix4& p_transform) { if (m_userNavFlag) { m_roi->UpdateTransformationRelativeToParent(p_transform); diff --git a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp index 7d7776a2..df7c3634 100644 --- a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp @@ -92,7 +92,7 @@ void IslePathActor::Enter() NavController()->ResetMaxLinearVel(m_maxLinearVel); SetUserActor(this); - FUN_1001b660(); + TurnAround(); TransformPointOfView(); } } @@ -151,7 +151,7 @@ void IslePathActor::Exit() GameState()->m_currentArea = LegoGameState::Area::e_vehicleExited; } - FUN_1001b660(); + TurnAround(); TransformPointOfView(); ResetViewVelocity(); } @@ -611,7 +611,7 @@ void IslePathActor::SpawnPlayer(LegoGameState::Area p_area, MxBool p_enter, MxU8 } // FUNCTION: LEGO1 0x1001b5b0 -void IslePathActor::VTable0xec(MxMatrix p_transform, LegoPathBoundary* p_boundary, MxBool p_reset) +void IslePathActor::UpdateWorld(MxMatrix p_transform, LegoPathBoundary* p_boundary, MxBool p_reset) { if (m_world) { m_world->RemoveActor(this); @@ -639,15 +639,15 @@ void IslePathActor::VTable0xec(MxMatrix p_transform, LegoPathBoundary* p_boundar // FUNCTION: LEGO1 0x1001b660 // FUNCTION: BETA10 0x10036ea2 -void IslePathActor::FUN_1001b660() +void IslePathActor::TurnAround() { MxMatrix transform(m_roi->GetLocal2World()); - Vector3 position(transform[0]); - Vector3 direction(transform[1]); - Vector3 up(transform[2]); + Vector3 right(transform[0]); + Vector3 up(transform[1]); + Vector3 direction(transform[2]); - up *= -1.0f; - position.EqualsCross(direction, up); + direction *= -1.0f; + right.EqualsCross(up, direction); m_roi->SetLocal2World(transform); m_roi->WrappedUpdateWorldData(); } diff --git a/LEGO1/lego/legoomni/src/actors/jetski.cpp b/LEGO1/lego/legoomni/src/actors/jetski.cpp index a85a5527..1afecc68 100644 --- a/LEGO1/lego/legoomni/src/actors/jetski.cpp +++ b/LEGO1/lego/legoomni/src/actors/jetski.cpp @@ -35,8 +35,8 @@ const char* g_varJSWNSHY5 = "c_jswnshy5"; Jetski::Jetski() { m_maxLinearVel = 25.0; - m_unk0x150 = 2.0; - m_unk0x148 = 1; + m_linearRotationRatio = 2.0; + m_canRotate = 1; } // FUNCTION: LEGO1 0x1007e630 diff --git a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp index e09168b1..bd1d6206 100644 --- a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp +++ b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp @@ -24,8 +24,8 @@ DECOMP_SIZE_ASSERT(Motocycle, 0x16c) Motocycle::Motocycle() { m_maxLinearVel = 40.0; - m_unk0x150 = 1.75; - m_unk0x148 = 1; + m_linearRotationRatio = 1.75; + m_canRotate = 1; m_fuel = 1.0; } diff --git a/LEGO1/lego/legoomni/src/actors/skateboard.cpp b/LEGO1/lego/legoomni/src/actors/skateboard.cpp index 09b847f7..473bd87e 100644 --- a/LEGO1/lego/legoomni/src/actors/skateboard.cpp +++ b/LEGO1/lego/legoomni/src/actors/skateboard.cpp @@ -22,8 +22,8 @@ SkateBoard::SkateBoard() { m_pizzaVisible = FALSE; m_maxLinearVel = 15.0; - m_unk0x150 = 3.5; - m_unk0x148 = 1; + m_linearRotationRatio = 3.5; + m_canRotate = 1; NotificationManager()->Register(this); } diff --git a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp index f5c92492..c26fa82d 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp @@ -123,7 +123,7 @@ void LegoCarBuildAnimPresenter::PutFrame() MoveShelfForward(); case e_stopped: if (m_carBuildEntity->GetROI()) { - FUN_1006b9a0(m_anim, m_shelfFrameBuffer, NULL); + ApplyTransformWithVisibilityAndCam(m_anim, m_shelfFrameBuffer, NULL); } default: break; @@ -591,7 +591,7 @@ void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle) m_platformAnimNodeData->GetRotationKey(0)->SetAngle(newRotation[3]); if (m_carBuildEntity->GetROI()) { - FUN_1006b9a0(&m_platformAnim, m_shelfFrameBuffer, NULL); + ApplyTransformWithVisibilityAndCam(&m_platformAnim, m_shelfFrameBuffer, NULL); } } } diff --git a/LEGO1/lego/legoomni/src/common/legoactioncontrolpresenter.cpp b/LEGO1/lego/legoomni/src/common/legoactioncontrolpresenter.cpp index 1afc9d64..266078ac 100644 --- a/LEGO1/lego/legoomni/src/common/legoactioncontrolpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/legoactioncontrolpresenter.cpp @@ -26,7 +26,7 @@ void LegoActionControlPresenter::ReadyTickle() m_subscriber->FreeDataChunk(chunk); if (m_compositePresenter) { if (m_action->GetDuration() == -1 || m_action->GetFlags() & 1) { - m_compositePresenter->VTable0x60(this); + m_compositePresenter->AdvanceSerialAction(this); } } } @@ -36,11 +36,11 @@ void LegoActionControlPresenter::ReadyTickle() void LegoActionControlPresenter::RepeatingTickle() { if (IsEnabled()) { - if (m_unk0x50 == 0) { + if (m_actionType == 0) { ParseExtra(); } - InvokeAction(m_unk0x50, MxAtomId(m_unk0x54.GetData(), e_lowerCase2), m_unk0x64, NULL); + InvokeAction(m_actionType, MxAtomId(m_sourceName.GetData(), e_lowerCase2), m_streamId, NULL); ProgressTickleState(e_done); } } @@ -84,15 +84,15 @@ void LegoActionControlPresenter::ParseExtra() char output[1024]; if (KeyValueStringParse(output, g_strACTION, extraCopy)) { - m_unk0x50 = MatchActionString(strtok(output, g_parseExtraTokens)); + m_actionType = MatchActionString(strtok(output, g_parseExtraTokens)); - if (m_unk0x50 != Extra::ActionType::e_exit) { + if (m_actionType != Extra::ActionType::e_exit) { MakeSourceName(extraCopy, strtok(NULL, g_parseExtraTokens)); - m_unk0x54 = extraCopy; - m_unk0x54.ToLowerCase(); - if (m_unk0x50 != Extra::ActionType::e_run) { - m_unk0x64 = atoi(strtok(NULL, g_parseExtraTokens)); + m_sourceName = extraCopy; + m_sourceName.ToLowerCase(); + if (m_actionType != Extra::ActionType::e_run) { + m_streamId = atoi(strtok(NULL, g_parseExtraTokens)); } } } diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 0f19e329..6f9cb71d 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -315,7 +315,7 @@ MxS32 g_legoAnimationManagerConfig = 1; float g_unk0x100f7500 = 0.1f; // GLOBAL: LEGO1 0x100f7504 -MxS32 g_unk0x100f7504 = 0; +MxS32 g_pathWalkingModeSelector = 0; // FUNCTION: LEGO1 0x1005eb50 void LegoAnimationManager::configureLegoAnimationManager(MxS32 p_legoAnimationManagerConfig) @@ -1933,10 +1933,10 @@ void LegoAnimationManager::AddExtra(MxS32 p_location, MxBool p_und) } if (i != m_numAllowedExtras) { - MxU8 und = SDL_rand(2) != 0 ? 1 : 2; + MxU8 pathWalkingMode = SDL_rand(2) != 0 ? 1 : 2; MxBool bool1, bool2; - switch (g_unk0x100f7504 % 4) { + switch (g_pathWalkingModeSelector % 4) { case 0: bool1 = FALSE; bool2 = FALSE; @@ -1954,7 +1954,7 @@ void LegoAnimationManager::AddExtra(MxS32 p_location, MxBool p_und) if (p_location < 0) { boundary = new LegoLocation::Boundary; - if (!FUN_10064120(boundary, und == 2, bool2)) { + if (!FUN_10064120(boundary, pathWalkingMode == 2, bool2)) { delete boundary; boundary = NULL; } @@ -2008,19 +2008,19 @@ void LegoAnimationManager::AddExtra(MxS32 p_location, MxBool p_und) g_characters[m_lastExtraCharacterId].m_name ); - switch (g_unk0x100f7504++ % 4) { + switch (g_pathWalkingModeSelector++ % 4) { case 0: - actor->SetUnknown0x0c(und != 1 ? 1 : 2); + actor->SetPathWalkingMode(pathWalkingMode != 1 ? 1 : 2); break; case 1: { - actor->SetUnknown0x0c(und); + actor->SetPathWalkingMode(pathWalkingMode); MxS32 src = boundary->m_src; boundary->m_src = boundary->m_dest; boundary->m_dest = src; break; } default: - actor->SetUnknown0x0c(und); + actor->SetPathWalkingMode(pathWalkingMode); break; } @@ -2190,21 +2190,21 @@ MxBool LegoAnimationManager::FUN_10062e20(LegoROI* p_roi, LegoAnimPresenter* p_p MxResult result = 1; // Not a valid MxResult value if (!local24) { - MxU8 unk0x0c; + MxU8 pathWalkingMode; switch (SDL_rand(3)) { case 0: - unk0x0c = 1; + pathWalkingMode = 1; break; case 1: - unk0x0c = 2; + pathWalkingMode = 2; break; case 2: - unk0x0c = 0; + pathWalkingMode = 0; break; } - actor->SetUnknown0x0c(unk0x0c); + actor->SetPathWalkingMode(pathWalkingMode); Mx3DPointFloat position; Mx3DPointFloat direction; @@ -2390,7 +2390,7 @@ MxBool LegoAnimationManager::FUN_10063b90(LegoWorld* p_world, LegoExtraActor* p_ presenter = (LegoLocomotionAnimPresenter*) p_world->Find("LegoAnimPresenter", vehicleWC); if (presenter != NULL) { - presenter->FUN_1006d680(p_actor, 1.7f); + presenter->CreateROIAndBuildMap(p_actor, 1.7f); } g_vehicles[g_characters[p_characterId].m_vehicleId].m_unk0x04 = FALSE; @@ -2403,7 +2403,7 @@ MxBool LegoAnimationManager::FUN_10063b90(LegoWorld* p_world, LegoExtraActor* p_ presenter = (LegoLocomotionAnimPresenter*) p_world->Find("LegoAnimPresenter", vehicleWC); if (presenter != NULL) { - presenter->FUN_1006d680(p_actor, 0.7f); + presenter->CreateROIAndBuildMap(p_actor, 0.7f); } } @@ -2416,7 +2416,7 @@ MxBool LegoAnimationManager::FUN_10063b90(LegoWorld* p_world, LegoExtraActor* p_ presenter = (LegoLocomotionAnimPresenter*) p_world->Find("LegoAnimPresenter", vehicleWC); if (presenter != NULL) { - presenter->FUN_1006d680(p_actor, 4.0f); + presenter->CreateROIAndBuildMap(p_actor, 4.0f); } } @@ -2429,7 +2429,7 @@ MxBool LegoAnimationManager::FUN_10063b90(LegoWorld* p_world, LegoExtraActor* p_ presenter = (LegoLocomotionAnimPresenter*) p_world->Find("LegoAnimPresenter", vehicleWC); if (presenter != NULL) { - presenter->FUN_1006d680(p_actor, 0.0f); + presenter->CreateROIAndBuildMap(p_actor, 0.0f); } } @@ -2701,8 +2701,8 @@ MxResult LegoAnimationManager::FUN_10064380( } if (actor != NULL) { - MxU8 unk0x0c = SDL_rand(2) != 0 ? 1 : 2; - actor->SetUnknown0x0c(unk0x0c); + MxU8 pathWalkingMode = SDL_rand(2) != 0 ? 1 : 2; + actor->SetPathWalkingMode(pathWalkingMode); actor->SetWorldSpeed(0.0f); if (world->PlaceActor(actor, p_boundaryName, p_src, p_srcScale, p_dest, p_destScale) != SUCCESS) { @@ -2718,12 +2718,12 @@ MxResult LegoAnimationManager::FUN_10064380( LegoLocomotionAnimPresenter* presenter = (LegoLocomotionAnimPresenter*) world->Find("LegoAnimPresenter", cycles[p_undIdx1]); if (presenter != NULL) { - presenter->FUN_1006d680(actor, 0.0f); + presenter->CreateROIAndBuildMap(actor, 0.0f); } presenter = (LegoLocomotionAnimPresenter*) world->Find("LegoAnimPresenter", cycles[p_undIdx2]); if (presenter != NULL) { - presenter->FUN_1006d680(actor, 4.0f); + presenter->CreateROIAndBuildMap(actor, 4.0f); } m_extras[i].m_unk0x08 = Timer()->GetTime(); diff --git a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp index af32a238..3512727e 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp @@ -152,7 +152,7 @@ void LegoAnimMMPresenter::ReadyTickle() } if (m_tranInfo != NULL && m_tranInfo->m_unk0x0c != NULL) { - m_presenter->VTable0xa0(*m_tranInfo->m_unk0x0c); + m_presenter->SetTransform(*m_tranInfo->m_unk0x0c); } if (m_presenter != NULL) { @@ -168,7 +168,7 @@ void LegoAnimMMPresenter::StartingTickle() { if (m_presenter == NULL || m_presenter->GetCurrentTickleState() == e_idle) { if (m_tranInfo != NULL && m_tranInfo->m_unk0x08 != NULL) { - m_presenter->FUN_1006b140(m_tranInfo->m_unk0x08); + m_presenter->CopyTransform(m_tranInfo->m_unk0x08); } m_unk0x50 = Timer()->GetTime(); @@ -225,7 +225,7 @@ MxLong LegoAnimMMPresenter::Notify(MxParam& p_param) } // FUNCTION: LEGO1 0x1004b360 -void LegoAnimMMPresenter::VTable0x60(MxPresenter* p_presenter) +void LegoAnimMMPresenter::AdvanceSerialAction(MxPresenter* p_presenter) { if (m_presenter == p_presenter && ((MxU8) p_presenter->GetCurrentTickleState() == MxPresenter::e_streaming || (MxU8) p_presenter->GetCurrentTickleState() == MxPresenter::e_done)) { @@ -316,7 +316,7 @@ MxBool LegoAnimMMPresenter::FUN_1004b450() MxBool LegoAnimMMPresenter::FUN_1004b530(MxLong p_time) { if (m_presenter != NULL) { - m_presenter->FUN_1006afc0(m_unk0x68, 0); + m_presenter->GetTransforms(m_unk0x68, 0); m_roiMap = m_presenter->GetROIMap(m_roiMapSize); m_roiMapSize++; } @@ -403,7 +403,7 @@ MxBool LegoAnimMMPresenter::FUN_1004b610(MxLong p_time) m_action->SetTimeStarted(Timer()->GetTime()); if (m_compositePresenter != NULL) { - m_compositePresenter->VTable0x60(this); + m_compositePresenter->AdvanceSerialAction(this); } return TRUE; @@ -471,10 +471,10 @@ MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time) } #ifdef BETA10 - actor->VTable0xa8(); + actor->ApplyLocal2World(); #else if (m_tranInfo->m_unk0x29) { - actor->VTable0xa8(); + actor->ApplyLocal2World(); } #endif } @@ -498,7 +498,7 @@ void LegoAnimMMPresenter::FUN_1004b840() MxDSAction* action = m_action; if (m_presenter != NULL) { - m_presenter->FUN_1006c7a0(); + m_presenter->ApplyFinishedTransform(); } for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { diff --git a/LEGO1/lego/legoomni/src/common/legotesttimer.cpp b/LEGO1/lego/legoomni/src/common/legotesttimer.cpp new file mode 100644 index 00000000..e40d9a62 --- /dev/null +++ b/LEGO1/lego/legoomni/src/common/legotesttimer.cpp @@ -0,0 +1,156 @@ +#include "legotesttimer.h" + +#include "legoeventnotificationparam.h" +#include "legoinputmanager.h" +#include "misc.h" +#include "mxnotificationparam.h" + +#include + +// FUNCTION: BETA10 0x100d1030 +LegoTestTimer::LegoTestTimer(LegoS32 p_numTimers, LegoS32 p_interval, LegoS32 p_numBins, LegoS32 p_type) +{ + m_enable = FALSE; + m_keyRegistered = FALSE; + + if (p_interval > 0) { + m_numTimers = p_numTimers; + m_interval = p_interval; + m_numBins = p_numBins / m_interval; + + m_lastTime = new LegoS32[m_numTimers]; + m_totalTime = new LegoS32[m_numTimers]; + m_timers = new LegoS32*[m_numTimers]; + + for (int i = 0; i < m_numTimers; i++) { + m_lastTime[i] = -1; + m_timers[i] = new LegoS32[m_numBins]; + for (int j = 0; j < m_numBins; j++) { + m_timers[i][j] = 0; + } + } + } + else { + m_numTimers = 0; + m_interval = 0; + m_numBins = 0; + m_lastTime = NULL; + m_totalTime = NULL; + m_timers = NULL; + } +} + +// FUNCTION: BETA10 0x100d11ee +LegoTestTimer::~LegoTestTimer() +{ + if (m_keyRegistered && InputManager()) { + InputManager()->UnRegister(this); + } + + m_enable = FALSE; + if (m_numTimers != 0) { + delete[] m_lastTime; + delete[] m_totalTime; + + for (int i = 0; i < m_numTimers; i++) { + delete m_timers[i]; + } + + delete[] m_timers; + } +} + +// FUNCTION: BETA10 0x100d132c +void LegoTestTimer::Tick(LegoS32 p_timer) +{ + if (m_enable) { + MxULong time = timeGetTime(); + LegoS32 prev = p_timer ? p_timer - 1 : 0; + if (m_lastTime[p_timer] == -1) { + m_lastTime[p_timer] = time; + m_totalTime[p_timer] = 0; + + for (int i = 0; i < m_numBins; i++) { + m_timers[p_timer][i] = 0; + } + } + else { + LegoS32 dtim = time - m_lastTime[prev]; + if (dtim < 0) { + dtim = 0; + } + + m_lastTime[p_timer] = time; + LegoS32 binIndex = dtim / m_interval; + if (binIndex >= m_numBins) { + binIndex = m_numBins - 1; + } + + m_timers[p_timer][binIndex]++; + m_totalTime[p_timer] += dtim; + } + } + else if (!m_keyRegistered) { + InputManager()->Register(this); + m_keyRegistered = TRUE; + } +} + +// FUNCTION: BETA10 0x100d148f +void LegoTestTimer::Print() +{ + FILE* f = fopen("\\TEST_TIME.TXT", "w"); + if (f) { + int i; + + fprintf(f, "timer"); + for (i = 0; i < m_numTimers; i++) { + fprintf(f, "%8d ", i); + } + + fprintf(f, "\n"); + for (int k = 0; k < m_numBins; k++) { + fprintf(f, "%3d: ", m_interval * (k + 1)); + for (int j = 0; j < m_numTimers; j++) { + fprintf(f, "%8d ", m_timers[j][k]); + } + fprintf(f, "\n"); + } + + fprintf(f, "ttime"); + for (i = 0; i < m_numTimers; i++) { + fprintf(f, "%8d ", m_totalTime[i]); + } + + fclose(f); + } + + ResetAtNextTick(); +} + +// FUNCTION: BETA10 0x100d161e +void LegoTestTimer::ResetAtNextTick() +{ + for (int i = 0; i < m_numTimers; i++) { + m_lastTime[i] = -1; + } +} + +// FUNCTION: BETA10 0x100d1667 +MxLong LegoTestTimer::Notify(MxParam& p_param) +{ + if (((MxNotificationParam&) p_param).GetNotification() == c_notificationKeyPress) { + MxU8 key = ((LegoEventNotificationParam&) p_param).GetKey(); + + if (key == 's' || key == 'S') { + ResetAtNextTick(); + m_enable = TRUE; + } + else if (key == 'p' || key == 'P') { + m_enable = FALSE; + Print(); + } + } + + return 0; +} diff --git a/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp b/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp index 7c6a788d..781c76b6 100644 --- a/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp @@ -15,8 +15,8 @@ DECOMP_SIZE_ASSERT(MxCompositeMediaPresenter, 0x50) // FUNCTION: LEGO1 0x10073ea0 MxCompositeMediaPresenter::MxCompositeMediaPresenter() { - m_unk0x4c = 0; - m_unk0x4e = FALSE; + m_remainingChildren = 0; + m_allChildrenStreaming = FALSE; VideoManager()->RegisterPresenter(*this); } @@ -99,25 +99,25 @@ void MxCompositeMediaPresenter::StartingTickle() { AUTOLOCK(m_criticalSection); - if (!m_unk0x4e) { + if (!m_allChildrenStreaming) { for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { if ((*it)->GetCurrentTickleState() < e_streaming) { (*it)->Tickle(); if ((*it)->GetCurrentTickleState() == e_streaming || ((*it)->GetAction() && (*it)->GetAction()->GetStartTime())) { - m_unk0x4c++; + m_remainingChildren++; } } } - if (m_list.size() == m_unk0x4c) { - m_unk0x4e = TRUE; - m_unk0x4c = 0; + if (m_list.size() == m_remainingChildren) { + m_allChildrenStreaming = TRUE; + m_remainingChildren = 0; for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { if (!(*it)->GetAction()->GetStartTime()) { - m_unk0x4c++; + m_remainingChildren++; } } } @@ -128,11 +128,11 @@ void MxCompositeMediaPresenter::StartingTickle() !((*it)->GetAction()->GetFlags() & MxDSAction::c_bit9)) { (*it)->Tickle(); (*it)->GetAction()->SetFlags((*it)->GetAction()->GetFlags() | MxDSAction::c_bit9); - m_unk0x4c--; + m_remainingChildren--; } } - if (!m_unk0x4c) { + if (!m_remainingChildren) { ProgressTickleState(e_streaming); MxLong time = Timer()->GetTime(); m_action->SetTimeStarted(time); diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp index d47103e2..aea8beb0 100644 --- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp @@ -142,11 +142,11 @@ LegoNavController::LegoNavController() m_linearAccel = 0.0f; m_rotationalAccel = 0.0f; m_trackDefault = FALSE; - m_unk0x5d = FALSE; + m_keyPressed = FALSE; m_isAccelerating = FALSE; - m_unk0x64 = 0.0f; - m_unk0x68 = 0.0f; - m_unk0x60 = 0.0f; + m_additionalScale = 0.0f; + m_additionalRotationY = 0.0f; + m_additionalHeightOffset = 0.0f; m_lastTime = Timer()->GetTime(); @@ -330,7 +330,7 @@ MxBool LegoNavController::CalculateNewPosDir( const Vector3& p_curDir, Vector3& p_newPos, Vector3& p_newDir, - const Vector3* p_und + const Vector3* p_up ) { if (!g_isWorldActive) { @@ -338,14 +338,14 @@ MxBool LegoNavController::CalculateNewPosDir( } MxBool changed = FALSE; - MxBool und = FALSE; + MxBool rotatedY = FALSE; MxTime currentTime = Timer()->GetTime(); float deltaTime = Min((currentTime - m_lastTime) / 1000.0, 1. / 10.); m_lastTime = currentTime; if (ProcessKeyboardInput() == FAILURE) { - ProcessJoystickInput(und); + ProcessJoystickInput(rotatedY); } if (m_useRotationalVel) { @@ -357,7 +357,7 @@ MxBool LegoNavController::CalculateNewPosDir( m_linearVel = CalculateNewVel(m_targetLinearVel, m_linearVel, m_linearAccel, deltaTime); - if (und || (Abs(m_rotationalVel) > m_zeroThreshold) || (Abs(m_linearVel) > m_zeroThreshold)) { + if (rotatedY || (Abs(m_rotationalVel) > m_zeroThreshold) || (Abs(m_linearVel) > m_zeroThreshold)) { float rot_mat[3][3]; Mx3DPointFloat delta_pos, new_dir, new_pos; @@ -376,7 +376,7 @@ MxBool LegoNavController::CalculateNewPosDir( delta_rad = DTOR(m_rotationalVel * m_rotSensitivity); } - if (p_und != NULL && (*p_und)[1] < 0.0f) { + if (p_up != NULL && (*p_up)[1] < 0.0f) { delta_rad = -delta_rad; } @@ -389,7 +389,7 @@ MxBool LegoNavController::CalculateNewPosDir( changed = TRUE; } - if (m_unk0x5d) { + if (m_keyPressed) { float rot_mat[3][3]; Mx3DPointFloat delta_pos, new_pos, new_dir; @@ -402,20 +402,20 @@ MxBool LegoNavController::CalculateNewPosDir( SET3(new_dir, p_curDir); } - if (m_unk0x64 != 0.0f) { - delta_pos[0] = new_dir[0] * m_unk0x64; - delta_pos[1] = new_dir[1] * m_unk0x64; - delta_pos[2] = new_dir[2] * m_unk0x64; + if (m_additionalScale != 0.0f) { + delta_pos[0] = new_dir[0] * m_additionalScale; + delta_pos[1] = new_dir[1] * m_additionalScale; + delta_pos[2] = new_dir[2] * m_additionalScale; } else { FILLVEC3(delta_pos, 0.0f); } - delta_pos[1] += m_unk0x60; + delta_pos[1] += m_additionalHeightOffset; VPV3(p_newPos, new_pos, delta_pos); - if (m_unk0x68 != 0.0f) { - float delta_rad = DTOR(m_unk0x68); + if (m_additionalRotationY != 0.0f) { + float delta_rad = DTOR(m_additionalRotationY); IDENTMAT3(rot_mat); rot_mat[0][0] = rot_mat[2][2] = cos(delta_rad); rot_mat[0][2] = rot_mat[2][0] = sin(delta_rad); @@ -426,8 +426,8 @@ MxBool LegoNavController::CalculateNewPosDir( SET3(p_newDir, new_dir); } - m_unk0x60 = m_unk0x64 = m_unk0x68 = 0.0f; - m_unk0x5d = FALSE; + m_additionalHeightOffset = m_additionalScale = m_additionalRotationY = 0.0f; + m_keyPressed = FALSE; changed = TRUE; } @@ -523,7 +523,7 @@ MxS32 LegoNavController::GetNumLocations() } // FUNCTION: LEGO1 0x10055750 -MxResult LegoNavController::ProcessJoystickInput(MxBool& p_und) +MxResult LegoNavController::ProcessJoystickInput(MxBool& p_rotatedY) { LegoOmni* instance = LegoOmni::GetInstance(); @@ -556,7 +556,7 @@ MxResult LegoNavController::ProcessJoystickInput(MxBool& p_und) if (world && world->GetCameraController()) { world->GetCameraController()->RotateY(DTOR(povPosition)); - p_und = TRUE; + p_rotatedY = TRUE; } } @@ -654,7 +654,7 @@ MxResult LegoNavController::ProcessKeyboardInput() MxLong LegoNavController::Notify(MxParam& p_param) { if (((MxNotificationParam&) p_param).GetNotification() == c_notificationKeyPress) { - m_unk0x5d = TRUE; + m_keyPressed = TRUE; SDL_Keycode originKey = ((LegoEventNotificationParam&) p_param).GetKey(); SDL_Keycode key = originKey; @@ -810,7 +810,7 @@ MxLong LegoNavController::Notify(MxParam& p_param) g_fpsEnabled = TRUE; } default: - m_unk0x5d = FALSE; + m_keyPressed = FALSE; break; case SDLK_0: case SDLK_1: @@ -978,7 +978,7 @@ MxLong LegoNavController::Notify(MxParam& p_param) g_locationCalcStep = 1; break; case SDLK_D: - m_unk0x60 = -1.0; + m_additionalHeightOffset = -1.0; break; case SDLK_F: RealtimeView::SetUserMaxLOD(0.0); @@ -1044,7 +1044,7 @@ MxLong LegoNavController::Notify(MxParam& p_param) BackgroundAudioManager()->Enable(g_enableMusic); break; case SDLK_U: - m_unk0x60 = 1.0; + m_additionalHeightOffset = 1.0; break; case SDLK_V: if (g_nextAnimation > 0 && g_animationCalcStep == 0) { diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index f8e9b3cb..976c9417 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -122,8 +122,8 @@ void LegoWorld::Destroy(MxBool p_fromDestructor) if (presenter->IsA("LegoLocomotionAnimPresenter")) { LegoLocomotionAnimPresenter* animPresenter = (LegoLocomotionAnimPresenter*) presenter; - animPresenter->DecrementUnknown0xd4(); - if (animPresenter->GetUnknown0xd4() == 0) { + animPresenter->DecrementWorldRefCounter(); + if (animPresenter->GetWorldRefCounter() == 0) { ApplyMask(action, MxDSAction::c_world, FALSE); presenter->EndAction(); } @@ -363,7 +363,7 @@ void LegoWorld::AddPresenterIfInRange(LegoAnimPresenter* p_presenter) LegoPathController* controller; while (cursor.Next(controller)) { - controller->FUN_100468f0(p_presenter); + controller->AddPresenterIfInRange(p_presenter); } } @@ -382,7 +382,7 @@ void LegoWorld::RemovePresenterFromBoundaries(LegoAnimPresenter* p_presenter) // FUNCTION: LEGO1 0x1001ff80 void LegoWorld::AddPath(LegoPathController* p_controller) { - p_controller->FUN_10046bb0(this); + p_controller->SetWorld(this); m_pathControllerList.Append(p_controller); } @@ -416,7 +416,7 @@ MxResult LegoWorld::GetCurrPathInfo(LegoPathBoundary** p_boundaries, MxS32& p_nu return FAILURE; } - return controller->FUN_10046b30(*p_boundaries, p_numL); + return controller->GetBoundaries(*p_boundaries, p_numL); } // FUNCTION: LEGO1 0x10020220 diff --git a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp index 17bfedf2..aa7d4b87 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp @@ -404,9 +404,9 @@ MxResult LegoWorldPresenter::LoadWorldModel(ModelDbModel& p_model, SDL_IOStream* } // FUNCTION: LEGO1 0x10067a70 -void LegoWorldPresenter::VTable0x60(MxPresenter* p_presenter) +void LegoWorldPresenter::AdvanceSerialAction(MxPresenter* p_presenter) { - MxCompositePresenter::VTable0x60(p_presenter); + MxCompositePresenter::AdvanceSerialAction(p_presenter); MxDSAction* action = p_presenter->GetAction(); if (action->GetDuration() != -1 && (action->GetFlags() & MxDSAction::c_looping) == 0) { diff --git a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp index 4fdaebc6..9ca28921 100644 --- a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp @@ -63,10 +63,10 @@ MxResult LegoAnimActor::GetTimeInCycle(float& p_timeInCycle) } // FUNCTION: LEGO1 0x1001c240 -void LegoAnimActor::VTable0x74(Matrix4& p_transform) +void LegoAnimActor::ApplyTransform(Matrix4& p_transform) { float timeInCycle; - LegoPathActor::VTable0x74(p_transform); + LegoPathActor::ApplyTransform(p_transform); if (m_curAnim >= 0) { GetTimeInCycle(timeInCycle); @@ -80,19 +80,19 @@ void LegoAnimActor::Animate(float p_time) { assert(m_roi); - if (m_lastTime == 0) { - m_lastTime = p_time - 1.0f; + if (m_transformTime == 0) { + m_transformTime = p_time - 1.0f; } if (m_actorState == c_initial && !m_userNavFlag && m_worldSpeed <= 0) { if (m_curAnim >= 0) { - MxMatrix transform(m_unk0xec); + MxMatrix transform(m_local2World); float timeInCycle; GetTimeInCycle(timeInCycle); AnimateWithTransform(timeInCycle, transform); } - m_lastTime = m_actorTime = p_time; + m_transformTime = m_actorTime = p_time; } else { LegoPathActor::Animate(p_time); @@ -109,7 +109,7 @@ MxResult LegoAnimActor::AnimateWithTransform(float p_time, Matrix4& p_transform) LegoROI** roiMap = m_animMaps[m_curAnim]->m_roiMap; MxU32 numROIs = m_animMaps[m_curAnim]->m_numROIs; - if (!m_boundary->GetFlag0x10()) { + if (!m_boundary->GetVisibility()) { MxU32 i; m_roi->SetVisibility(FALSE); @@ -244,7 +244,7 @@ void LegoAnimActor::ParseAction(char* p_extra) token = strtok(NULL, g_parseExtraTokens); if (token) { - p->FUN_1006d680(this, atof(token)); + p->CreateROIAndBuildMap(this, atof(token)); } } diff --git a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp index e6f7153a..7e01f24b 100644 --- a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp @@ -12,7 +12,7 @@ DECOMP_SIZE_ASSERT(LegoExtraActor, 0x1dc) // GLOBAL: LEGO1 0x100f31d0 -LegoWorld* g_unk0x100f31d0 = NULL; +LegoWorld* g_reassemblyAnimWorld = NULL; // GLOBAL: LEGO1 0x100f31d4 LegoLocomotionAnimPresenter* m_assAnimP = NULL; @@ -21,7 +21,7 @@ LegoLocomotionAnimPresenter* m_assAnimP = NULL; LegoLocomotionAnimPresenter* m_disAnimP = NULL; // GLOBAL: LEGO1 0x100f31dc -MxS32 g_unk0x100f31dc = 0; +MxS32 g_hitCounter = 0; // GLOBAL: LEGO1 0x10104c18 Mx3DPointFloat g_unk0x10104c18 = Mx3DPointFloat(0.0f, 2.5f, 0.0f); @@ -32,12 +32,12 @@ LegoExtraActor::LegoExtraActor() { m_lastPathStruct = 0.0f; m_scheduledTime = 0; - m_unk0x0c = 0; - m_unk0x0e = 0; - m_whichAnim = 0; + m_pathWalkingMode = 0; + m_animationAtCurrentBoundary = FALSE; + m_reassemblyAnimation = e_none; m_assAnim = NULL; m_disAnim = NULL; - m_unk0x15 = 0; + m_hitBlockCounter = 0; } // FUNCTION: LEGO1 0x1002a6b0 @@ -48,19 +48,19 @@ LegoExtraActor::~LegoExtraActor() } // FUNCTION: LEGO1 0x1002a720 -MxU32 LegoExtraActor::VTable0x90(float p_time, Matrix4& p_transform) +MxU32 LegoExtraActor::StepState(float p_time, Matrix4& p_transform) { switch (m_actorState & c_maxState) { case c_initial: - case c_one: + case c_ready: return TRUE; - case c_two: + case c_hit: m_scheduledTime = p_time + 2000.0f; - m_actorState = c_three; - m_actorTime += (p_time - m_lastTime) * m_worldSpeed; - m_lastTime = p_time; + m_actorState = c_hitAnimation; + m_actorTime += (p_time - m_transformTime) * m_worldSpeed; + m_transformTime = p_time; return FALSE; - case c_three: { + case c_hitAnimation: { Vector3 positionRef(p_transform[3]); p_transform = m_roi->GetLocal2World(); @@ -89,9 +89,9 @@ MxU32 LegoExtraActor::VTable0x90(float p_time, Matrix4& p_transform) } positionRef = position; - m_actorTime += (p_time - m_lastTime) * m_worldSpeed; - m_lastTime = p_time; - VTable0x74(p_transform); + m_actorTime += (p_time - m_transformTime) * m_worldSpeed; + m_transformTime = p_time; + ApplyTransform(p_transform); return FALSE; } else { @@ -109,32 +109,32 @@ MxU32 LegoExtraActor::VTable0x90(float p_time, Matrix4& p_transform) } // FUNCTION: LEGO1 0x1002aa90 -void LegoExtraActor::VTable0xa4(MxBool& p_und1, MxS32& p_und2) +void LegoExtraActor::GetWalkingBehavior(MxBool& p_countCounterclockWise, MxS32& p_selectedEdgeIndex) { - switch (m_unk0x0c) { + switch (m_pathWalkingMode) { case 1: - p_und1 = TRUE; - p_und2 = 1; + p_countCounterclockWise = TRUE; + p_selectedEdgeIndex = 1; break; case 2: - p_und1 = FALSE; - p_und2 = 1; + p_countCounterclockWise = FALSE; + p_selectedEdgeIndex = 1; break; default: - p_und1 = TRUE; - p_und2 = 1 + SDL_rand(p_und2); + p_countCounterclockWise = TRUE; + p_selectedEdgeIndex = 1 + SDL_rand(p_selectedEdgeIndex); break; } } // FUNCTION: LEGO1 0x1002aae0 -MxResult LegoExtraActor::FUN_1002aae0() +MxResult LegoExtraActor::SwitchDirection() { LegoPathBoundary* oldEdge = m_boundary; - Vector3 rightRef(m_unk0xec[0]); - Vector3 upRef(m_unk0xec[1]); - Vector3 dirRef(m_unk0xec[2]); - Vector3 positionRef(m_unk0xec[3]); + Vector3 rightRef(m_local2World[0]); + Vector3 upRef(m_local2World[1]); + Vector3 dirRef(m_local2World[2]); + Vector3 positionRef(m_local2World[3]); dirRef *= -1.0f; rightRef.EqualsCross(upRef, dirRef); @@ -150,23 +150,23 @@ MxResult LegoExtraActor::FUN_1002aae0() m_boundary = oldEdge; } - LegoPathActor::VTable0x9c(); + LegoPathActor::CalculateSpline(); return SUCCESS; } -inline void LegoExtraActor::FUN_1002ad8a() +inline void LegoExtraActor::InitializeReassemblyAnim() { LegoWorld* w = CurrentWorld(); - if (g_unk0x100f31d0 != w) { - g_unk0x100f31d0 = w; + if (g_reassemblyAnimWorld != w) { + g_reassemblyAnimWorld = w; m_assAnimP = (LegoLocomotionAnimPresenter*) w->Find("LegoAnimPresenter", "BNsAss01"); m_disAnimP = (LegoLocomotionAnimPresenter*) w->Find("LegoAnimPresenter", "BNsDis01"); } if (!m_assAnim) { MxS32 index = 0; - m_assAnimP->FUN_1006d680(this, -20.0f); + m_assAnimP->CreateROIAndBuildMap(this, -20.0f); for (MxS32 i = 0; i < m_animMaps.size(); i++) { if (m_animMaps[i]->GetWorldSpeed() == -20.0f) { @@ -178,7 +178,7 @@ inline void LegoExtraActor::FUN_1002ad8a() if (!m_disAnim) { MxS32 index = 0; - m_disAnimP->FUN_1006d680(this, -21.0f); + m_disAnimP->CreateROIAndBuildMap(this, -21.0f); for (MxS32 i = 0; i < m_animMaps.size(); i++) { if (m_animMaps[i]->GetWorldSpeed() == -21.0f) { @@ -198,26 +198,26 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) } if (p_bool) { - if (m_unk0x15 != 0) { + if (m_hitBlockCounter != 0) { return FAILURE; } - m_unk0x15 = 100; - FUN_1002aae0(); + m_hitBlockCounter = 100; + SwitchDirection(); } else { MxU32 b = FALSE; - if (++g_unk0x100f31dc % 2 == 0) { - MxMatrix matrix(p_actor->GetROI()->GetLocal2World()); - MxMatrix matrix2(m_roi->GetLocal2World()); + if (++g_hitCounter % 2 == 0) { + MxMatrix otherActorLocal(p_actor->GetROI()->GetLocal2World()); + MxMatrix local(m_roi->GetLocal2World()); - m_unk0x18 = matrix2; - Vector3 positionRef(matrix2[3]); - Mx3DPointFloat dir(matrix[2]); + m_localBeforeHit = local; + Vector3 positionRef(local[3]); + Mx3DPointFloat otherActorDir(otherActorLocal[2]); - dir *= 2.0f; - positionRef += dir; + otherActorDir *= 2.0f; + positionRef += otherActorDir; for (MxS32 i = 0; i < m_boundary->GetNumEdges(); i++) { Mx4DPointFloat* normal = m_boundary->GetEdgeNormal(i); @@ -229,9 +229,9 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) } if (!b) { - m_roi->SetLocal2World(matrix2); + m_roi->SetLocal2World(local); m_roi->WrappedUpdateWorldData(); - FUN_1002ad8a(); + InitializeReassemblyAnim(); assert(m_roi); assert(SoundManager()->GetCacheSoundManager()); SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE); @@ -242,8 +242,8 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) m_prevWorldSpeed = GetWorldSpeed(); VTable0xc4(); SetWorldSpeed(0); - m_whichAnim = 1; - SetActorState(c_one | c_noCollide); + m_reassemblyAnimation = e_disassemble; + SetActorState(c_ready | c_noCollide); } } @@ -255,7 +255,7 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) EmitGameEvent(e_hitActor); } VTable0xc4(); - SetActorState(c_two | c_noCollide); + SetActorState(c_hit | c_noCollide); Mx3DPointFloat dir = p_actor->GetWorldDirection(); MxMatrix matrix3 = MxMatrix(roi->GetLocal2World()); Vector3 positionRef(matrix3[3]); @@ -278,25 +278,25 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) } // FUNCTION: LEGO1 0x1002b290 -MxResult LegoExtraActor::VTable0x9c() +MxResult LegoExtraActor::CalculateSpline() { LegoPathBoundary* oldBoundary = m_boundary; - MxResult result = LegoPathActor::VTable0x9c(); + MxResult result = LegoPathActor::CalculateSpline(); if (m_boundary != oldBoundary) { - MxU32 b = FALSE; + MxU32 foundAnimation = FALSE; LegoAnimPresenterSet& presenters = m_boundary->GetPresenters(); for (LegoAnimPresenterSet::iterator it = presenters.begin(); it != presenters.end(); it++) { MxU32 roiMapSize; if ((*it)->GetROIMap(roiMapSize)) { - b = TRUE; + foundAnimation = TRUE; break; } } - if (b) { - m_unk0x0e = 1; + if (foundAnimation) { + m_animationAtCurrentBoundary = TRUE; m_prevWorldSpeed = GetWorldSpeed(); SetWorldSpeed(0); } @@ -308,21 +308,21 @@ MxResult LegoExtraActor::VTable0x9c() // FUNCTION: LEGO1 0x1002b370 void LegoExtraActor::Restart() { - if (m_unk0x0e != 0) { - MxU32 b = FALSE; + if (m_animationAtCurrentBoundary != 0) { + MxU32 foundAnimation = FALSE; LegoAnimPresenterSet& presenters = m_boundary->GetPresenters(); for (LegoAnimPresenterSet::iterator it = presenters.begin(); it != presenters.end(); it++) { MxU32 roiMapSize; if ((*it)->GetROIMap(roiMapSize)) { - b = TRUE; + foundAnimation = TRUE; break; } } - if (!b) { + if (!foundAnimation) { SetWorldSpeed(m_prevWorldSpeed); - m_unk0x0e = 0; + m_animationAtCurrentBoundary = FALSE; } } } @@ -332,14 +332,14 @@ void LegoExtraActor::Animate(float p_time) { LegoAnimActorStruct* laas = NULL; - switch (m_whichAnim) { - case 0: + switch (m_reassemblyAnimation) { + case e_none: LegoAnimActor::Animate(p_time); break; - case 1: + case e_disassemble: if (m_scheduledTime < p_time) { - m_whichAnim = 2; - m_actorState = c_one | c_noCollide; + m_reassemblyAnimation = e_assemble; + m_actorState = c_ready | c_noCollide; m_scheduledTime = m_assAnim->GetDuration() + p_time; break; } @@ -347,13 +347,13 @@ void LegoExtraActor::Animate(float p_time) laas = m_disAnim; break; } - case 2: + case e_assemble: if (m_scheduledTime < p_time) { - m_whichAnim = 0; + m_reassemblyAnimation = e_none; m_actorState = c_initial; SetWorldSpeed(m_prevWorldSpeed); - m_roi->SetLocal2World(m_unk0x18); - m_lastTime = p_time; + m_roi->SetLocal2World(m_localBeforeHit); + m_transformTime = p_time; break; } else { @@ -385,10 +385,10 @@ void LegoExtraActor::Animate(float p_time) } // FUNCTION: LEGO1 0x1002b5d0 -void LegoExtraActor::VTable0x74(Matrix4& p_transform) +void LegoExtraActor::ApplyTransform(Matrix4& p_transform) { - if (m_whichAnim == 0) { - LegoAnimActor::VTable0x74(p_transform); + if (m_reassemblyAnimation == e_none) { + LegoAnimActor::ApplyTransform(p_transform); } } @@ -415,32 +415,32 @@ void LegoExtraActor::VTable0xc4() if (b) { float duration = m_animMaps[m_curAnim]->GetDuration(); - MxMatrix matrix(m_unk0xec); + MxMatrix matrix(m_local2World); LegoAnimActor::AnimateWithTransform(duration, matrix); } } } // FUNCTION: LEGO1 0x1002b6f0 -MxS32 LegoExtraActor::VTable0x68(Vector3& p_point1, Vector3& p_point2, Vector3& p_point3) +MxS32 LegoExtraActor::CheckIntersections(Vector3& p_rayOrigin, Vector3& p_rayEnd, Vector3& p_intersectionPoint) { - return LegoPathActor::VTable0x68(p_point1, p_point2, p_point3); + return LegoPathActor::CheckIntersections(p_rayOrigin, p_rayEnd, p_intersectionPoint); } // FUNCTION: LEGO1 0x1002b980 -inline MxU32 LegoExtraActor::VTable0x6c( +inline MxU32 LegoExtraActor::CheckPresenterAndActorIntersections( LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint ) { LegoAnimPresenterSet& presenters = p_boundary->GetPresenters(); for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) { - if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) { + if ((*itap)->Intersect(p_rayOrigin, p_rayDirection, p_rayLength, p_radius, p_intersectionPoint)) { return 1; } } @@ -459,14 +459,14 @@ inline MxU32 LegoExtraActor::VTable0x6c( if (actor->GetUserNavFlag()) { MxMatrix local2world = roi->GetLocal2World(); Vector3 local60(local2world[3]); - Mx3DPointFloat local54(p_v1); + Mx3DPointFloat local54(p_rayOrigin); local54 -= local60; - float local1c = p_v2.Dot(p_v2, p_v2); - float local24 = p_v2.Dot(p_v2, local54) * 2.0f; + float local1c = p_rayDirection.Dot(p_rayDirection, p_rayDirection); + float local24 = p_rayDirection.Dot(p_rayDirection, local54) * 2.0f; float local20 = local54.Dot(local54, local54); - if (m_unk0x15 != 0 && local20 < 10.0f) { + if (m_hitBlockCounter != 0 && local20 < 10.0f) { return 0; } @@ -493,9 +493,10 @@ inline MxU32 LegoExtraActor::VTable0x6c( local1cX = local40; } - if ((local20X >= 0.0f && local20X <= p_f1) || (local1cX >= 0.0f && local1cX <= p_f1) || - (local20X <= -0.01 && p_f1 + 0.01 <= local1cX)) { - p_v3 = p_v1; + if ((local20X >= 0.0f && local20X <= p_rayLength) || + (local1cX >= 0.0f && local1cX <= p_rayLength) || + (local20X <= -0.01 && p_rayLength + 0.01 <= local1cX)) { + p_intersectionPoint = p_rayOrigin; if (HitActor(actor, TRUE) < 0) { return 0; @@ -508,7 +509,14 @@ inline MxU32 LegoExtraActor::VTable0x6c( } } else { - if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) { + if (roi->Intersect( + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint, + m_collideBox && actor->GetCollideBox() + )) { if (HitActor(actor, TRUE) < 0) { return 0; } @@ -522,8 +530,8 @@ inline MxU32 LegoExtraActor::VTable0x6c( } } - if (m_unk0x15 != 0) { - m_unk0x15--; + if (m_hitBlockCounter != 0) { + m_hitBlockCounter--; } return 0; diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 6c0498f2..a91a51be 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -45,18 +45,18 @@ LegoPathActor::LegoPathActor() { m_boundary = NULL; m_actorTime = 0; - m_lastTime = 0; - m_unk0x7c = 0; + m_transformTime = 0; + m_traveledDistance = 0; m_userNavFlag = FALSE; m_actorState = c_initial; m_grec = NULL; m_pathController = NULL; m_collideBox = FALSE; - m_unk0x148 = 0; - m_unk0x14c = 0; - m_unk0x140 = 0.0099999999f; - m_unk0x144 = 0.8f; - m_unk0x150 = 2.0f; + m_canRotate = 0; + m_lastRotationAngle = 0; + m_wallHitDirectionFactor = 0.0099999999f; + m_wallHitDampening = 0.8f; + m_linearRotationRatio = 2.0f; } // FUNCTION: LEGO1 0x1002d820 @@ -70,19 +70,24 @@ LegoPathActor::~LegoPathActor() // FUNCTION: LEGO1 0x1002d8d0 // FUNCTION: BETA10 0x100ae8cd -MxResult LegoPathActor::VTable0x80(const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4) +MxResult LegoPathActor::SetSpline( + const Vector3& p_start, + Vector3& p_tangentAtStart, + Vector3& p_end, + Vector3& p_tangentAtEnd +) { - Mx3DPointFloat p1, p2, p3; + Mx3DPointFloat length, tangentAtStart, tangentAtEnd; - p1 = p_point3; - p1 -= p_point1; - m_BADuration = p1.LenSquared(); + length = p_end; + length -= p_start; + m_BADuration = length.LenSquared(); if (m_BADuration > 0.0f) { m_BADuration = sqrtf(m_BADuration); - p2 = p_point2; - p3 = p_point4; - m_unk0x8c.FUN_1009a140(p_point1, p2, p_point3, p3); + tangentAtStart = p_tangentAtStart; + tangentAtEnd = p_tangentAtEnd; + m_spline.SetSpline(p_start, tangentAtStart, p_end, tangentAtEnd); m_BADuration /= 0.001; return SUCCESS; } @@ -94,7 +99,7 @@ MxResult LegoPathActor::VTable0x80(const Vector3& p_point1, Vector3& p_point2, V // FUNCTION: LEGO1 0x1002d9c0 // FUNCTION: BETA10 0x100ae9da -MxResult LegoPathActor::VTable0x88( +MxResult LegoPathActor::SetTransformAndDestinationFromEdge( LegoPathBoundary* p_boundary, float p_time, LegoEdge& p_srcEdge, @@ -108,29 +113,29 @@ MxResult LegoPathActor::VTable0x88( Vector3* v3 = p_destEdge.CWVertex(*p_boundary); Vector3* v4 = p_destEdge.CCWVertex(*p_boundary); - Mx3DPointFloat p1, p2, p3, p4, p5; + Mx3DPointFloat start, end, destNormal, startDirection, endDirection; - p1 = *v2; - p1 -= *v1; - p1 *= p_srcScale; - p1 += *v1; + start = *v2; + start -= *v1; + start *= p_srcScale; + start += *v1; - p2 = *v4; - p2 -= *v3; - p2 *= p_destScale; - p2 += *v3; + end = *v4; + end -= *v3; + end *= p_destScale; + end += *v3; m_boundary = p_boundary; m_destEdge = &p_destEdge; - m_unk0xe4 = p_destScale; - m_unk0x7c = 0; - m_lastTime = p_time; + m_destScale = p_destScale; + m_traveledDistance = 0; + m_transformTime = p_time; m_actorTime = p_time; - p_destEdge.GetFaceNormal(*p_boundary, p3); + p_destEdge.GetFaceNormal(*p_boundary, destNormal); - p4 = p2; - p4 -= p1; - p4.Unitize(); + startDirection = end; + startDirection -= start; + startDirection.Unitize(); MxMatrix matrix; Vector3 pos(matrix[3]); @@ -139,8 +144,8 @@ MxResult LegoPathActor::VTable0x88( Vector3 right(matrix[0]); matrix.SetIdentity(); - pos = p1; - dir = p4; + pos = start; + dir = startDirection; up = *m_boundary->GetUp(); if (!m_cameraFlag || !m_userNavFlag) { @@ -151,10 +156,10 @@ MxResult LegoPathActor::VTable0x88( m_roi->UpdateTransformationRelativeToParent(matrix); if (!m_cameraFlag || !m_userNavFlag) { - p5.EqualsCross(*p_boundary->GetUp(), p3); - p5.Unitize(); + endDirection.EqualsCross(*p_boundary->GetUp(), destNormal); + endDirection.Unitize(); - if (VTable0x80(p1, p4, p2, p5) == SUCCESS) { + if (SetSpline(start, startDirection, end, endDirection) == SUCCESS) { m_boundary->AddActor(this); } else { @@ -166,17 +171,17 @@ MxResult LegoPathActor::VTable0x88( TransformPointOfView(); } - m_unk0xec = m_roi->GetLocal2World(); + m_local2World = m_roi->GetLocal2World(); return SUCCESS; } // FUNCTION: LEGO1 0x1002de10 // FUNCTION: BETA10 0x100aee61 -MxResult LegoPathActor::VTable0x84( +MxResult LegoPathActor::SetTransformAndDestinationFromPoints( LegoPathBoundary* p_boundary, float p_time, - Vector3& p_p1, - Vector3& p_p4, + Vector3& p_start, + Vector3& p_direction, LegoOrientedEdge* p_destEdge, float p_destScale ) @@ -188,20 +193,20 @@ MxResult LegoPathActor::VTable0x84( assert(v3 && v4); - Mx3DPointFloat p2, p3, p5; + Mx3DPointFloat end, destNormal, endDirection; - p2 = *v4; - p2 -= *v3; - p2 *= p_destScale; - p2 += *v3; + end = *v4; + end -= *v3; + end *= p_destScale; + end += *v3; m_boundary = p_boundary; m_destEdge = p_destEdge; - m_unk0xe4 = p_destScale; - m_unk0x7c = 0; - m_lastTime = p_time; + m_destScale = p_destScale; + m_traveledDistance = 0; + m_transformTime = p_time; m_actorTime = p_time; - p_destEdge->GetFaceNormal(*p_boundary, p3); + p_destEdge->GetFaceNormal(*p_boundary, destNormal); MxMatrix matrix; Vector3 pos(matrix[3]); @@ -210,8 +215,8 @@ MxResult LegoPathActor::VTable0x84( Vector3 right(matrix[0]); matrix.SetIdentity(); - pos = p_p1; - dir = p_p4; + pos = p_start; + dir = p_direction; up = *m_boundary->GetUp(); if (!m_cameraFlag || !m_userNavFlag) { @@ -226,10 +231,10 @@ MxResult LegoPathActor::VTable0x84( TransformPointOfView(); } else { - p5.EqualsCross(*p_boundary->GetUp(), p3); - p5.Unitize(); + endDirection.EqualsCross(*p_boundary->GetUp(), destNormal); + endDirection.Unitize(); - if (VTable0x80(p_p1, p_p4, p2, p5) != SUCCESS) { + if (SetSpline(p_start, p_direction, end, endDirection) != SUCCESS) { MxTrace("Warning: m_BADuration = %g, roi = %s\n", m_BADuration, m_roi->GetName()); return FAILURE; } @@ -237,57 +242,59 @@ MxResult LegoPathActor::VTable0x84( m_boundary->AddActor(this); } - m_unk0xec = m_roi->GetLocal2World(); + m_local2World = m_roi->GetLocal2World(); return SUCCESS; } // FUNCTION: LEGO1 0x1002e100 // FUNCTION: BETA10 0x100b0520 -MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) +MxS32 LegoPathActor::CalculateTransform(float p_time, Matrix4& p_transform) { if (m_userNavFlag && m_actorState == c_initial) { - m_lastTime = p_time; + m_transformTime = p_time; - Mx3DPointFloat p1, p2, p3, p4, p5; - p5 = Vector3(m_roi->GetWorldDirection()); - p4 = Vector3(m_roi->GetWorldPosition()); + Mx3DPointFloat newDir, newPos, intersectionPoint, pos, dir; + dir = Vector3(m_roi->GetWorldDirection()); + pos = Vector3(m_roi->GetWorldPosition()); LegoNavController* nav = NavController(); assert(nav); m_worldSpeed = nav->GetLinearVel(); - if (nav->CalculateNewPosDir(p4, p5, p2, p1, m_boundary->GetUp())) { - Mx3DPointFloat p6; - p6 = p2; + if (nav->CalculateNewPosDir(pos, dir, newPos, newDir, m_boundary->GetUp())) { + Mx3DPointFloat newPosCopy; + newPosCopy = newPos; MxS32 result = 0; - m_unk0xe9 = m_boundary->Intersect(m_roi->GetWorldBoundingSphere().Radius(), p4, p2, p3, m_destEdge); - if (m_unk0xe9 == -1) { + m_finishedTravel = + m_boundary + ->Intersect(m_roi->GetWorldBoundingSphere().Radius(), pos, newPos, intersectionPoint, m_destEdge); + if (m_finishedTravel == -1) { MxTrace("Intersect returned -1\n"); return -1; } else { - if (m_unk0xe9 != 0) { - p2 = p3; + if (m_finishedTravel != FALSE) { + newPos = intersectionPoint; } } - result = VTable0x68(p4, p2, p3); + result = CheckIntersections(pos, newPos, intersectionPoint); if (result > 0) { - p2 = p4; - m_unk0xe9 = 0; + newPos = pos; + m_finishedTravel = FALSE; result = 0; } else { - m_boundary->CheckAndCallPathTriggers(p4, p2, this); + m_boundary->CheckAndCallPathTriggers(pos, newPos, this); } LegoPathBoundary* oldBoundary = m_boundary; - if (m_unk0xe9 != 0) { - VTable0x9c(); + if (m_finishedTravel != FALSE) { + CalculateSpline(); if (m_boundary == oldBoundary) { MxLong time = Timer()->GetTime(); @@ -301,15 +308,15 @@ MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) } } - m_worldSpeed *= m_unk0x144; + m_worldSpeed *= m_wallHitDampening; nav->SetLinearVel(m_worldSpeed); - Mx3DPointFloat p7(p2); - p7 -= p6; + Mx3DPointFloat newPosDelta(newPos); + newPosDelta -= newPosCopy; - if (p7.Unitize() == 0) { - float f = sqrt(p1.LenSquared()) * m_unk0x140; - p7 *= f; - p1 += p7; + if (newPosDelta.Unitize() == 0) { + float f = sqrt(newDir.LenSquared()) * m_wallHitDirectionFactor; + newPosDelta *= f; + newDir += newPosDelta; } } } @@ -321,7 +328,7 @@ MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) Vector3 dir(p_transform[2]); Vector3 pos(p_transform[3]); - dir = p1; + dir = newDir; up = *m_boundary->GetUp(); right.EqualsCross(up, dir); @@ -329,7 +336,7 @@ MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) assert(res == 0); dir.EqualsCross(right, up); - pos = p2; + pos = newPos; return result; } else { @@ -337,47 +344,47 @@ MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) } } else if (p_time >= 0 && m_worldSpeed > 0) { - float f = (m_BADuration - m_unk0x7c) / m_worldSpeed + m_lastTime; + float endTime = (m_BADuration - m_traveledDistance) / m_worldSpeed + m_transformTime; - if (f < p_time) { - m_unk0x7c = m_BADuration; - m_unk0xe9 = 1; + if (endTime < p_time) { + m_traveledDistance = m_BADuration; + m_finishedTravel = TRUE; } else { - f = p_time; - m_unk0x7c += (f - m_lastTime) * m_worldSpeed; - m_unk0xe9 = 0; + endTime = p_time; + m_traveledDistance += (endTime - m_transformTime) * m_worldSpeed; + m_finishedTravel = FALSE; } - m_actorTime += (f - m_lastTime) * m_worldSpeed; - m_lastTime = f; + m_actorTime += (endTime - m_transformTime) * m_worldSpeed; + m_transformTime = endTime; p_transform.SetIdentity(); LegoResult r; if (m_userNavFlag) { - r = m_unk0x8c.FUN_1009a1e0(m_unk0x7c / m_BADuration, p_transform, *m_boundary->GetUp(), 0); + r = m_spline.Evaluate(m_traveledDistance / m_BADuration, p_transform, *m_boundary->GetUp(), FALSE); } else { - r = m_unk0x8c.FUN_1009a1e0(m_unk0x7c / m_BADuration, p_transform, *m_boundary->GetUp(), 1); + r = m_spline.Evaluate(m_traveledDistance / m_BADuration, p_transform, *m_boundary->GetUp(), TRUE); } assert(r == 0); // SUCCESS - Vector3 pos1(p_transform[3]); - Vector3 pos2(m_unk0xec[3]); + Vector3 end(p_transform[3]); + Vector3 origin(m_local2World[3]); Mx3DPointFloat p1; - if (VTable0x68(pos2, pos1, p1) > 0) { - m_lastTime = p_time; + if (CheckIntersections(origin, end, p1) > 0) { + m_transformTime = p_time; return 1; } else { - m_boundary->CheckAndCallPathTriggers(pos2, pos1, this); - pos2 = pos1; + m_boundary->CheckAndCallPathTriggers(origin, end, this); + origin = end; } - if (m_unk0xe9 != 0) { - VTable0x9c(); + if (m_finishedTravel != FALSE) { + CalculateSpline(); } } else { @@ -389,7 +396,7 @@ MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) // FUNCTION: LEGO1 0x1002e740 // FUNCTION: BETA10 0x100b0f70 -void LegoPathActor::VTable0x74(Matrix4& p_transform) +void LegoPathActor::ApplyTransform(Matrix4& p_transform) { if (m_userNavFlag) { m_roi->WrappedSetLocal2WorldWithWorldDataUpdate(p_transform); @@ -410,69 +417,70 @@ void LegoPathActor::VTable0x74(Matrix4& p_transform) void LegoPathActor::Animate(float p_time) { MxMatrix transform; - MxU32 b = FALSE; + MxU32 applyTransform = FALSE; - while (m_lastTime < p_time) { - if (m_actorState != c_initial && !VTable0x90(p_time, transform)) { + while (m_transformTime < p_time) { + if (m_actorState != c_initial && !StepState(p_time, transform)) { return; } - if (VTable0x8c(p_time, transform) != 0) { + if (CalculateTransform(p_time, transform) != 0) { break; } - m_unk0xec = transform; - b = TRUE; + m_local2World = transform; + applyTransform = TRUE; - if (m_unk0xe9 != 0) { + if (m_finishedTravel != FALSE) { break; } } - if (m_userNavFlag && m_unk0x148) { + if (m_userNavFlag && m_canRotate) { LegoNavController* nav = NavController(); - float vel = (nav->GetLinearVel() > 0) - ? -(nav->GetRotationalVel() / (nav->GetMaxLinearVel() * m_unk0x150) * nav->GetLinearVel()) - : 0; + float vel = + (nav->GetLinearVel() > 0) + ? -(nav->GetRotationalVel() / (nav->GetMaxLinearVel() * m_linearRotationRatio) * nav->GetLinearVel()) + : 0; - if ((MxS32) vel != m_unk0x14c) { - m_unk0x14c = vel; + if ((MxS32) vel != m_lastRotationAngle) { + m_lastRotationAngle = vel; LegoWorld* world = CurrentWorld(); if (world) { - world->GetCameraController()->RotateZ(DTOR(m_unk0x14c)); + world->GetCameraController()->RotateZ(DTOR(m_lastRotationAngle)); } } } - if (b) { - VTable0x74(transform); + if (applyTransform) { + ApplyTransform(transform); } } // FUNCTION: LEGO1 0x1002e8b0 // FUNCTION: BETA10 0x100af2f7 -void LegoPathActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoOrientedEdge*& p_edge, float& p_unk0xe4) +void LegoPathActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoOrientedEdge*& p_edge, float& p_scale) { assert(m_boundary); - m_boundary->SwitchBoundary(this, p_boundary, p_edge, p_unk0xe4); + m_boundary->SwitchBoundary(this, p_boundary, p_edge, p_scale); } // FUNCTION: LEGO1 0x1002e8d0 // FUNCTION: BETA10 0x100b1010 -MxU32 LegoPathActor::VTable0x6c( +MxU32 LegoPathActor::CheckPresenterAndActorIntersections( LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint ) { LegoAnimPresenterSet& presenters = p_boundary->GetPresenters(); for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) { - if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) { + if ((*itap)->Intersect(p_rayOrigin, p_rayDirection, p_rayLength, p_radius, p_intersectionPoint)) { return 1; } } @@ -488,7 +496,14 @@ MxU32 LegoPathActor::VTable0x6c( LegoROI* roi = actor->GetROI(); if (roi != NULL && (roi->GetVisibility() || actor->GetCameraFlag())) { - if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->m_collideBox)) { + if (roi->Intersect( + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint, + m_collideBox && actor->m_collideBox + )) { HitActor(actor, TRUE); actor->HitActor(this, FALSE); return 2; @@ -501,26 +516,33 @@ MxU32 LegoPathActor::VTable0x6c( return 0; } -inline MxU32 LegoPathActor::FUN_1002edd0( - list& p_boundaries, +inline MxU32 LegoPathActor::CheckIntersectionBothFaces( + list& p_checkedBoundaries, LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3, - MxS32 p_und + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint, + MxS32 p_depth ) { - MxU32 result = VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3); + MxU32 result = CheckPresenterAndActorIntersections( + p_boundary, + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint + ); if (result != 0) { return result; } - p_boundaries.push_back(p_boundary); + p_checkedBoundaries.push_back(p_boundary); - if (p_und >= 2) { + if (p_depth >= 2) { return 0; } @@ -532,14 +554,23 @@ inline MxU32 LegoPathActor::FUN_1002edd0( if (boundary != NULL) { list::const_iterator it; - for (it = p_boundaries.begin(); !(it == p_boundaries.end()); it++) { + for (it = p_checkedBoundaries.begin(); !(it == p_checkedBoundaries.end()); it++) { if ((*it) == boundary) { break; } } - if (it == p_boundaries.end()) { - result = FUN_1002edd0(p_boundaries, boundary, p_v1, p_v2, p_f1, p_f2, p_v3, p_und + 1); + if (it == p_checkedBoundaries.end()) { + result = CheckIntersectionBothFaces( + p_checkedBoundaries, + boundary, + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint, + p_depth + 1 + ); if (result != 0) { return result; @@ -553,26 +584,35 @@ inline MxU32 LegoPathActor::FUN_1002edd0( // FUNCTION: LEGO1 0x1002ebe0 // FUNCTION: BETA10 0x100af35e -MxS32 LegoPathActor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) +MxS32 LegoPathActor::CheckIntersections(Vector3& p_rayOrigin, Vector3& p_rayEnd, Vector3& p_intersectionPoint) { assert(m_boundary && m_roi); - Mx3DPointFloat v2(p_v2); - v2 -= p_v1; + Mx3DPointFloat rayDirection(p_rayEnd); + rayDirection -= p_rayOrigin; - float len = v2.LenSquared(); + float len = rayDirection.LenSquared(); if (len <= 0.001) { return 0; } len = sqrt((double) len); - v2 /= len; + rayDirection /= len; float radius = m_roi->GetWorldBoundingSphere().Radius(); list boundaries; - return FUN_1002edd0(boundaries, m_boundary, p_v1, v2, len, radius, p_v3, 0); + return CheckIntersectionBothFaces( + boundaries, + m_boundary, + p_rayOrigin, + rayDirection, + len, + radius, + p_intersectionPoint, + 0 + ); } // FUNCTION: LEGO1 0x1002f020 @@ -623,20 +663,21 @@ void LegoPathActor::ParseAction(char* p_extra) // FUNCTION: LEGO1 0x1002f1b0 // FUNCTION: BETA10 0x100af899 -MxResult LegoPathActor::VTable0x9c() +MxResult LegoPathActor::CalculateSpline() { - Mx3DPointFloat local34; - Mx3DPointFloat local48; - MxU32 local1c = 1; - MxU32 local20 = 1; + Mx3DPointFloat targetPosition; + Mx3DPointFloat endDirection; + MxU32 noPath1 = TRUE; + MxU32 noPath2 = TRUE; if (m_grec != NULL) { - if (m_grec->GetBit1()) { - local1c = 0; - local20 = 0; + if (m_grec->HasPath()) { + noPath1 = FALSE; + noPath2 = FALSE; Mx3DPointFloat vec; - switch (m_pathController->FUN_1004a240(*m_grec, local34, local48, m_unk0xe4, m_destEdge, m_boundary)) { + switch (m_pathController + ->GetNextPathEdge(*m_grec, targetPosition, endDirection, m_destScale, m_destEdge, m_boundary)) { case 0: case 1: break; @@ -651,30 +692,30 @@ MxResult LegoPathActor::VTable0x9c() } } - if (local1c != 0) { - SwitchBoundary(m_boundary, m_destEdge, m_unk0xe4); + if (noPath1 != FALSE) { + SwitchBoundary(m_boundary, m_destEdge, m_destScale); } - if (local20 != 0) { - Mx3DPointFloat local78; + if (noPath2 != FALSE) { + Mx3DPointFloat normal; assert(m_boundary && m_destEdge); - Vector3* v1 = m_destEdge->CWVertex(*m_boundary); - Vector3* v2 = m_destEdge->CCWVertex(*m_boundary); + Vector3* cw = m_destEdge->CWVertex(*m_boundary); + Vector3* ccw = m_destEdge->CCWVertex(*m_boundary); - assert(v1 && v2); + assert(cw && ccw); - LERP3(local34, *v1, *v2, m_unk0xe4); + LERP3(targetPosition, *cw, *ccw, m_destScale); - m_destEdge->GetFaceNormal(*m_boundary, local78); - local48.EqualsCross(*m_boundary->GetUp(), local78); - local48.Unitize(); + m_destEdge->GetFaceNormal(*m_boundary, normal); + endDirection.EqualsCross(*m_boundary->GetUp(), normal); + endDirection.Unitize(); } - Vector3 rightRef(m_unk0xec[0]); - Vector3 upRef(m_unk0xec[1]); - Vector3 dirRef(m_unk0xec[2]); + Vector3 rightRef(m_local2World[0]); + Vector3 upRef(m_local2World[1]); + Vector3 dirRef(m_local2World[2]); upRef = *m_boundary->GetUp(); @@ -684,74 +725,74 @@ MxResult LegoPathActor::VTable0x9c() dirRef.EqualsCross(rightRef, upRef); dirRef.Unitize(); - Mx3DPointFloat localc0(m_unk0xec[3]); - Mx3DPointFloat local84(m_unk0xec[2]); - Mx3DPointFloat local70(local34); + Mx3DPointFloat start(m_local2World[3]); + Mx3DPointFloat direction(m_local2World[2]); + Mx3DPointFloat startToTarget(targetPosition); - local70 -= localc0; - float len = local70.LenSquared(); + startToTarget -= start; + float len = startToTarget.LenSquared(); if (len >= 0.0f) { len = sqrt(len); - local84 *= len; - local48 *= len; + direction *= len; + endDirection *= len; } if (!m_userNavFlag) { - local84 *= -1.0f; + direction *= -1.0f; } - if (VTable0x80(localc0, local84, local34, local48) != SUCCESS) { + if (SetSpline(start, direction, targetPosition, endDirection) != SUCCESS) { MxTrace("Warning: m_BADuration = %g, roi = %s\n", m_BADuration, m_roi->GetName()); return FAILURE; } - m_unk0x7c = 0.0f; + m_traveledDistance = 0.0f; return SUCCESS; } // FUNCTION: LEGO1 0x1002f650 // FUNCTION: BETA10 0x100afd67 -void LegoPathActor::VTable0xa4(MxBool& p_und1, MxS32& p_und2) +void LegoPathActor::GetWalkingBehavior(MxBool& p_countCounterclockWise, MxS32& p_selectedEdgeIndex) { switch (GetActorId()) { case c_pepper: - p_und1 = TRUE; - p_und2 = 2; + p_countCounterclockWise = TRUE; + p_selectedEdgeIndex = 2; break; case c_mama: - p_und1 = FALSE; - p_und2 = 1; + p_countCounterclockWise = FALSE; + p_selectedEdgeIndex = 1; break; case c_papa: - p_und1 = TRUE; - p_und2 = 1; + p_countCounterclockWise = TRUE; + p_selectedEdgeIndex = 1; break; case c_nick: case c_brickster: - p_und1 = TRUE; - p_und2 = SDL_rand(p_und2) + 1; + p_countCounterclockWise = TRUE; + p_selectedEdgeIndex = SDL_rand(p_selectedEdgeIndex) + 1; break; case c_laura: - p_und1 = FALSE; - p_und2 = 2; + p_countCounterclockWise = FALSE; + p_selectedEdgeIndex = 2; break; default: - p_und1 = TRUE; - p_und2 = 1; + p_countCounterclockWise = TRUE; + p_selectedEdgeIndex = 1; break; } } // FUNCTION: LEGO1 0x1002f700 // FUNCTION: BETA10 0x100afe4c -void LegoPathActor::VTable0xa8() +void LegoPathActor::ApplyLocal2World() { - m_lastTime = Timer()->GetTime(); - m_roi->SetLocal2World(m_unk0xec); + m_transformTime = Timer()->GetTime(); + m_roi->SetLocal2World(m_local2World); m_roi->WrappedUpdateWorldData(); if (m_userNavFlag) { - m_roi->WrappedSetLocal2WorldWithWorldDataUpdate(m_unk0xec); + m_roi->WrappedSetLocal2WorldWithWorldDataUpdate(m_local2World); TransformPointOfView(); } } diff --git a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp index 31600f3e..b5adf6d6 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp @@ -89,7 +89,7 @@ void LegoPathBoundary::SwitchBoundary( LegoPathActor* p_actor, LegoPathBoundary*& p_boundary, LegoOrientedEdge*& p_edge, - float& p_unk0xe4 + float& p_scale ) { LegoOrientedEdge* e = p_edge; @@ -101,7 +101,7 @@ void LegoPathBoundary::SwitchBoundary( newBoundary = p_boundary; } - MxS32 local10 = 0; + MxS32 availableEdgeCount = 0; MxU8 userNavFlag; if (e->BETA_1004a830(*newBoundary, 1)) { @@ -113,38 +113,38 @@ void LegoPathBoundary::SwitchBoundary( do { p_edge = (LegoOrientedEdge*) p_edge->GetCounterclockwiseEdge(*newBoundary); - LegoPathBoundary* local20 = (LegoPathBoundary*) p_edge->OtherFace(newBoundary); + LegoPathBoundary* otherBoundary = (LegoPathBoundary*) p_edge->OtherFace(newBoundary); - if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*local20, 1))) { - local10++; + if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*otherBoundary, 1))) { + availableEdgeCount++; } } while (p_edge != e); - MxBool localc = TRUE; - MxS32 local8 = local10 - 1; + MxBool countCounterclockwise = TRUE; + MxS32 selectedEdgeIndex = availableEdgeCount - 1; - if (local10 <= 1) { - local8 = 0; + if (availableEdgeCount <= 1) { + selectedEdgeIndex = 0; } - else if (local10 == 2) { - local8 = 1; + else if (availableEdgeCount == 2) { + selectedEdgeIndex = 1; } else { - p_actor->VTable0xa4(localc, local8); + p_actor->GetWalkingBehavior(countCounterclockwise, selectedEdgeIndex); } - while (local8 > 0) { - if (localc) { + while (selectedEdgeIndex > 0) { + if (countCounterclockwise) { p_edge = (LegoOrientedEdge*) p_edge->GetCounterclockwiseEdge(*newBoundary); } else { p_edge = (LegoOrientedEdge*) p_edge->GetClockwiseEdge(*newBoundary); } - LegoPathBoundary* local20 = (LegoPathBoundary*) p_edge->OtherFace(newBoundary); + LegoPathBoundary* otherBoundary = (LegoPathBoundary*) p_edge->OtherFace(newBoundary); - if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*local20, 1))) { - local8--; + if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*otherBoundary, 1))) { + selectedEdgeIndex--; } } @@ -159,7 +159,7 @@ void LegoPathBoundary::SwitchBoundary( p_boundary->AddActor(p_actor); } else { - p_unk0xe4 = 1.0 - p_unk0xe4; + p_scale = 1.0 - p_scale; } } else { @@ -176,7 +176,7 @@ void LegoPathBoundary::SwitchBoundary( p_edge = (LegoOrientedEdge*) p_edge->GetCounterclockwiseEdge(*p_boundary); } - p_unk0xe4 = 1.0 - p_unk0xe4; + p_scale = 1.0 - p_scale; } } @@ -184,127 +184,128 @@ void LegoPathBoundary::SwitchBoundary( // FUNCTION: BETA10 0x100b1adc MxU32 LegoPathBoundary::Intersect( float p_scale, - Vector3& p_point1, - Vector3& p_point2, - Vector3& p_point3, + Vector3& p_oldPos, + Vector3& p_newPos, + Vector3& p_intersectionPoint, LegoOrientedEdge*& p_edge ) { LegoOrientedEdge* e = NULL; - float localc; - MxU32 local10 = 0; + float minHitDistance; + MxU32 normalizedCalculated = 0; float len = 0.0f; - Mx3DPointFloat vec; + Mx3DPointFloat direction; for (MxS32 i = 0; i < m_numEdges; i++) { LegoOrientedEdge* edge = (LegoOrientedEdge*) m_edges[i]; - if (p_point2.Dot(m_edgeNormals[i], p_point2) + m_edgeNormals[i][3] <= -1e-07) { - if (local10 == 0) { - local10 = 1; - vec = p_point2; - vec -= p_point1; + if (p_newPos.Dot(m_edgeNormals[i], p_newPos) + m_edgeNormals[i][3] <= -1e-07) { + if (normalizedCalculated == FALSE) { + normalizedCalculated = TRUE; + direction = p_newPos; + direction -= p_oldPos; - len = vec.LenSquared(); + len = direction.LenSquared(); if (len <= 0.0f) { return 0; } len = sqrt(len); - vec /= len; + direction /= len; } - float dot = vec.Dot(vec, m_edgeNormals[i]); + float dot = direction.Dot(direction, m_edgeNormals[i]); if (dot != 0.0f) { - float local34 = (-m_edgeNormals[i][3] - p_point1.Dot(p_point1, m_edgeNormals[i])) / dot; + float hitDistance = (-m_edgeNormals[i][3] - p_oldPos.Dot(p_oldPos, m_edgeNormals[i])) / dot; - if (local34 >= -0.001 && local34 <= len && (e == NULL || local34 < localc)) { + if (hitDistance >= -0.001 && hitDistance <= len && (e == NULL || hitDistance < minHitDistance)) { e = edge; - localc = local34; + minHitDistance = hitDistance; } } } } if (e != NULL) { - if (localc < 0.0f) { - localc = 0.0f; + if (minHitDistance < 0.0f) { + minHitDistance = 0.0f; } - Mx3DPointFloat local50; - Mx3DPointFloat local70; - Vector3* local5c = e->CWVertex(*this); + Mx3DPointFloat startToPosition; + Mx3DPointFloat edgeNormal; + Vector3* start = e->CWVertex(*this); - p_point3 = vec; - p_point3 *= localc; - p_point3 += p_point1; + p_intersectionPoint = direction; + p_intersectionPoint *= minHitDistance; + p_intersectionPoint += p_oldPos; - local50 = p_point2; - local50 -= *local5c; + startToPosition = p_newPos; + startToPosition -= *start; - e->GetFaceNormal(*this, local70); + e->GetFaceNormal(*this, edgeNormal); - float local58 = local50.Dot(local50, local70); - LegoOrientedEdge* local54 = NULL; + float projection = startToPosition.Dot(startToPosition, edgeNormal); + LegoOrientedEdge* candidateEdge = NULL; - if (local58 < 0.0f) { - Mx3DPointFloat local84; + if (projection < 0.0f) { + Mx3DPointFloat candidateEdgeNormal; - for (LegoOrientedEdge* local88 = (LegoOrientedEdge*) e->GetClockwiseEdge(*this); e != local88; - local88 = (LegoOrientedEdge*) local88->GetClockwiseEdge(*this)) { - local88->GetFaceNormal(*this, local84); + for (LegoOrientedEdge* cwEdge = (LegoOrientedEdge*) e->GetClockwiseEdge(*this); e != cwEdge; + cwEdge = (LegoOrientedEdge*) cwEdge->GetClockwiseEdge(*this)) { + cwEdge->GetFaceNormal(*this, candidateEdgeNormal); - if (local84.Dot(local84, local70) <= 0.9) { + if (candidateEdgeNormal.Dot(candidateEdgeNormal, edgeNormal) <= 0.9) { break; } - Vector3* local90 = local88->CWVertex(*this); - Mx3DPointFloat locala4(p_point3); - locala4 -= *local90; + Vector3* candidateStart = cwEdge->CWVertex(*this); + Mx3DPointFloat candidateToIntersection(p_intersectionPoint); + candidateToIntersection -= *candidateStart; - float local8c = locala4.Dot(locala4, local84); + float candidateProjection = candidateToIntersection.Dot(candidateToIntersection, candidateEdgeNormal); - if (local8c > local58 && local8c < local88->m_length) { - local54 = local88; - local58 = local8c; - local70 = local84; - local5c = local90; + if (candidateProjection > projection && candidateProjection < cwEdge->m_length) { + candidateEdge = cwEdge; + projection = candidateProjection; + edgeNormal = candidateEdgeNormal; + start = candidateStart; } } } else { - if (e->m_length < local58) { - Mx3DPointFloat localbc; + if (e->m_length < projection) { + Mx3DPointFloat candidateEdgeNormal; - for (LegoOrientedEdge* locala8 = (LegoOrientedEdge*) e->GetCounterclockwiseEdge(*this); e != locala8; - locala8 = (LegoOrientedEdge*) locala8->GetCounterclockwiseEdge(*this)) { - locala8->GetFaceNormal(*this, localbc); + for (LegoOrientedEdge* ccwEdge = (LegoOrientedEdge*) e->GetCounterclockwiseEdge(*this); e != ccwEdge; + ccwEdge = (LegoOrientedEdge*) ccwEdge->GetCounterclockwiseEdge(*this)) { + ccwEdge->GetFaceNormal(*this, candidateEdgeNormal); - if (localbc.Dot(localbc, local70) <= 0.9) { + if (candidateEdgeNormal.Dot(candidateEdgeNormal, edgeNormal) <= 0.9) { break; } - Vector3* localc4 = locala8->CWVertex(*this); - Mx3DPointFloat locald8(p_point3); - locald8 -= *localc4; + Vector3* candidateStart = ccwEdge->CWVertex(*this); + Mx3DPointFloat candidateToIntersection(p_intersectionPoint); + candidateToIntersection -= *candidateStart; - float localc0 = locald8.Dot(locald8, localbc); + float candidateProjection = + candidateToIntersection.Dot(candidateToIntersection, candidateEdgeNormal); - if (localc0 < local58 && localc0 >= 0.0f) { - local54 = locala8; - local58 = localc0; - local70 = localbc; - local5c = localc4; + if (candidateProjection < projection && candidateProjection >= 0.0f) { + candidateEdge = ccwEdge; + projection = candidateProjection; + edgeNormal = candidateEdgeNormal; + start = candidateStart; } } } } - if (local54 != NULL) { - e = local54; + if (candidateEdge != NULL) { + e = candidateEdge; } - if (local58 <= 0.0f) { + if (projection <= 0.0f) { if (!e->GetMask0x03()) { p_edge = (LegoOrientedEdge*) e->GetClockwiseEdge(*this); } @@ -312,18 +313,18 @@ MxU32 LegoPathBoundary::Intersect( p_edge = e; } - p_point3 = *local5c; + p_intersectionPoint = *start; return 2; } - else if (local58 > 0.0f && e->m_length > local58) { - p_point3 = local70; - p_point3 *= local58; - p_point3 += *local5c; + else if (projection > 0.0f && e->m_length > projection) { + p_intersectionPoint = edgeNormal; + p_intersectionPoint *= projection; + p_intersectionPoint += *start; p_edge = e; return 1; } else { - p_point3 = *e->CCWVertex(*this); + p_intersectionPoint = *e->CCWVertex(*this); if (!e->GetMask0x03()) { p_edge = (LegoOrientedEdge*) e->GetCounterclockwiseEdge(*this); @@ -343,15 +344,15 @@ MxU32 LegoPathBoundary::Intersect( // FUNCTION: BETA10 0x100b2220 MxU32 LegoPathBoundary::AddPresenterIfInRange(LegoAnimPresenter* p_presenter) { - Mx3DPointFloat unk0x30; + Mx3DPointFloat centerDistance; - unk0x30 = m_centerPoint; - unk0x30 -= p_presenter->m_unk0xa8; + centerDistance = m_centerPoint; + centerDistance -= p_presenter->m_centerPoint; - float len = unk0x30.LenSquared(); - float local20 = p_presenter->m_unk0xa4 + m_boundingRadius; + float len = centerDistance.LenSquared(); + float radiusSquared = p_presenter->m_boundingRadius + m_boundingRadius; - if (len > 0.001 && len > local20 * local20) { + if (len > 0.001 && len > radiusSquared * radiusSquared) { return 0; } diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index 9a3ac922..c89cafbd 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -14,10 +14,10 @@ DECOMP_SIZE_ASSERT(LegoPathController::CtrlBoundary, 0x08) DECOMP_SIZE_ASSERT(LegoPathController::CtrlEdge, 0x08) // GLOBAL: LEGO1 0x100d7cc8 -MxU32 g_unk0x100d7cc8[] = {2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0}; +MxU32 g_ctrlEdgesNamesA[] = {2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0}; // GLOBAL: LEGO1 0x100d7d08 -MxU32 g_unk0x100d7d08[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +MxU32 g_ctrlEdgesNamesB[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // GLOBAL: LEGO1 0x100f42e8 // GLOBAL: BETA10 0x101f25f0 @@ -28,7 +28,7 @@ LegoPathController::CtrlBoundary* LegoPathController::g_ctrlBoundariesA = NULL; LegoPathController::CtrlEdge* LegoPathController::g_ctrlEdgesA = NULL; // GLOBAL: LEGO1 0x100f42f0 -const char* LegoPathController::g_unk0x100f42f0[] = { +const char* LegoPathController::g_ctrlBoundariesNamesA[] = { "edg03_21", "edg03_23", "edg03_30", @@ -48,7 +48,7 @@ const char* LegoPathController::g_unk0x100f42f0[] = { }; // GLOBAL: LEGO1 0x100f4330 -const char* LegoPathController::g_unk0x100f4330[] = { +const char* LegoPathController::g_ctrlBoundariesNamesB[] = { "edg03_06", "edg03_21", "edg03_30", @@ -108,23 +108,23 @@ MxResult LegoPathController::Create( LegoPathBoundary& boundary = m_boundaries[i]; MxS32 j; - for (j = 0; j < sizeOfArray(g_unk0x100f42f0); j++) { - if (!SDL_strcasecmp(g_unk0x100f42f0[j], boundary.GetName())) { + for (j = 0; j < sizeOfArray(g_ctrlBoundariesNamesA); j++) { + if (!SDL_strcasecmp(g_ctrlBoundariesNamesA[j], boundary.GetName())) { g_ctrlBoundariesA[j].m_controller = this; g_ctrlBoundariesA[j].m_boundary = &boundary; - MxU32 edge = g_unk0x100d7cc8[j]; + MxU32 edge = g_ctrlEdgesNamesA[j]; g_ctrlEdgesA[j].m_controller = this; g_ctrlEdgesA[j].m_edge = boundary.GetEdges()[edge]; } } - for (j = 0; j < sizeOfArray(g_unk0x100f4330); j++) { - if (!SDL_strcasecmp(g_unk0x100f4330[j], boundary.GetName())) { + for (j = 0; j < sizeOfArray(g_ctrlBoundariesNamesB); j++) { + if (!SDL_strcasecmp(g_ctrlBoundariesNamesB[j], boundary.GetName())) { g_ctrlBoundariesB[j].m_controller = this; g_ctrlBoundariesB[j].m_boundary = &boundary; g_ctrlEdgesB[j].m_controller = this; - g_ctrlEdgesB[j].m_edge = boundary.GetEdges()[g_unk0x100d7d08[j]]; + g_ctrlEdgesB[j].m_edge = boundary.GetEdges()[g_ctrlEdgesNamesB[j]]; } } } @@ -170,7 +170,7 @@ void LegoPathController::Destroy() m_numE = 0; MxS32 j; - for (j = 0; j < sizeOfArray(g_unk0x100f42f0); j++) { + for (j = 0; j < sizeOfArray(g_ctrlBoundariesNamesA); j++) { if (g_ctrlBoundariesA[j].m_controller == this) { g_ctrlBoundariesA[j].m_controller = NULL; g_ctrlBoundariesA[j].m_boundary = NULL; @@ -182,7 +182,7 @@ void LegoPathController::Destroy() } } - for (j = 0; j < sizeOfArray(g_unk0x100f4330); j++) { + for (j = 0; j < sizeOfArray(g_ctrlBoundariesNamesB); j++) { if (g_ctrlBoundariesB[j].m_controller == this) { g_ctrlBoundariesB[j].m_controller = NULL; g_ctrlBoundariesB[j].m_boundary = NULL; @@ -199,7 +199,7 @@ void LegoPathController::Destroy() // FUNCTION: BETA10 0x100b6d60 MxResult LegoPathController::Tickle() { - FUN_10046970(); + AnimateActors(); return SUCCESS; } @@ -230,8 +230,14 @@ MxResult LegoPathController::PlaceActor( assert(pSrcE && pDestE); float time = Timer()->GetTime(); - MxResult result = - p_actor->VTable0x88(pBoundary, time, *pSrcE, p_srcScale, (LegoOrientedEdge&) *pDestE, p_destScale); + MxResult result = p_actor->SetTransformAndDestinationFromEdge( + pBoundary, + time, + *pSrcE, + p_srcScale, + (LegoOrientedEdge&) *pDestE, + p_destScale + ); if (result != SUCCESS) { assert(0); @@ -305,7 +311,8 @@ MxResult LegoPathController::PlaceActor( return FAILURE; } - if (p_actor->VTable0x84(boundary, time, p_position, p_direction, edge, 0.5f) == SUCCESS) { + if (p_actor->SetTransformAndDestinationFromPoints(boundary, time, p_position, p_direction, edge, 0.5f) == + SUCCESS) { p_actor->SetController(this); m_actors.insert(p_actor); return SUCCESS; @@ -350,7 +357,7 @@ MxResult LegoPathController::RemoveActor(LegoPathActor* p_actor) // FUNCTION: LEGO1 0x100468f0 // FUNCTION: BETA10 0x100b72f7 -void LegoPathController::FUN_100468f0(LegoAnimPresenter* p_presenter) +void LegoPathController::AddPresenterIfInRange(LegoAnimPresenter* p_presenter) { for (MxS32 i = 0; i < m_numL; i++) { if (!(m_boundaries[i].m_flags & LegoWEGEdge::c_bit3)) { @@ -370,7 +377,7 @@ void LegoPathController::RemovePresenterFromBoundaries(LegoAnimPresenter* p_pres // FUNCTION: LEGO1 0x10046970 // FUNCTION: BETA10 0x100b73d8 -void LegoPathController::FUN_10046970() +void LegoPathController::AnimateActors() { float time = Timer()->GetTime(); @@ -388,7 +395,7 @@ void LegoPathController::FUN_10046970() } // FUNCTION: LEGO1 0x10046b30 -MxResult LegoPathController::FUN_10046b30(LegoPathBoundary*& p_boundaries, MxS32& p_numL) +MxResult LegoPathController::GetBoundaries(LegoPathBoundary*& p_boundaries, MxS32& p_numL) { p_boundaries = m_boundaries; p_numL = m_numL; @@ -410,7 +417,7 @@ LegoPathBoundary* LegoPathController::GetPathBoundary(const char* p_name) // FUNCTION: LEGO1 0x10046bb0 // FUNCTION: BETA10 0x100b75bc -void LegoPathController::FUN_10046bb0(LegoWorld* p_world) +void LegoPathController::SetWorld(LegoWorld* p_world) { for (MxS32 i = 0; i < m_numT; i++) { m_structs[i].SetWorld(p_world); @@ -437,10 +444,10 @@ MxResult LegoPathController::Init() return FAILURE; } - g_ctrlBoundariesA = new CtrlBoundary[sizeOfArray(g_unk0x100f42f0)]; - g_ctrlEdgesA = new CtrlEdge[sizeOfArray(g_unk0x100f42f0)]; - g_ctrlBoundariesB = new CtrlBoundary[sizeOfArray(g_unk0x100f4330)]; - g_ctrlEdgesB = new CtrlEdge[sizeOfArray(g_unk0x100f4330)]; + g_ctrlBoundariesA = new CtrlBoundary[sizeOfArray(g_ctrlBoundariesNamesA)]; + g_ctrlEdgesA = new CtrlEdge[sizeOfArray(g_ctrlBoundariesNamesA)]; + g_ctrlBoundariesB = new CtrlBoundary[sizeOfArray(g_ctrlBoundariesNamesB)]; + g_ctrlEdgesB = new CtrlEdge[sizeOfArray(g_ctrlBoundariesNamesB)]; return SUCCESS; } @@ -765,7 +772,7 @@ MxResult LegoPathController::ReadVector(LegoStorage* p_storage, Mx4DPointFloat& // FUNCTION: LEGO1 0x10048310 // FUNCTION: BETA10 0x100b8911 -MxResult LegoPathController::FUN_10048310( +MxResult LegoPathController::FindPath( LegoPathEdgeContainer* p_grec, const Vector3& p_oldPosition, const Vector3& p_oldDirection, @@ -774,7 +781,7 @@ MxResult LegoPathController::FUN_10048310( const Vector3& p_newDirection, LegoPathBoundary* p_newBoundary, LegoU8 p_mask, - MxFloat* p_param9 + MxFloat* p_distance ) { p_grec->m_position = p_newPosition; @@ -782,22 +789,22 @@ MxResult LegoPathController::FUN_10048310( p_grec->m_boundary = p_newBoundary; if (p_newBoundary == p_oldBoundary) { - p_grec->SetBit1(TRUE); + p_grec->SetPath(TRUE); return SUCCESS; } - list boundaryList; - list::iterator boundaryListIt; + list boundaryList; + list::iterator boundaryListIt; - LegoBEWithFloatSet boundarySet; - LegoBEWithFloatSet::iterator boundarySetItA; - LegoBEWithFloatSet::iterator boundarySetItB; + LegoBEWithMidpointSet boundarySet; + LegoBEWithMidpointSet::iterator boundarySetItA; + LegoBEWithMidpointSet::iterator boundarySetItB; LegoPathCtrlEdgeSet pathCtrlEdgeSet(m_pfsE); - MxFloat local14 = 999999.0f; + MxFloat minDistance = 999999.0f; - p_grec->SetBit1(FALSE); + p_grec->SetPath(FALSE); for (MxS32 i = 0; i < p_oldBoundary->GetNumEdges(); i++) { LegoPathCtrlEdge* edge = (LegoPathCtrlEdge*) p_oldBoundary->GetEdges()[i]; @@ -809,15 +816,16 @@ MxResult LegoPathController::FUN_10048310( if (p_newBoundary == otherFace) { float dist; if ((dist = edge->DistanceToMidpoint(p_oldPosition) + edge->DistanceToMidpoint(p_newPosition)) < - local14) { - local14 = dist; + minDistance) { + minDistance = dist; p_grec->erase(p_grec->begin(), p_grec->end()); - p_grec->SetBit1(TRUE); + p_grec->SetPath(TRUE); p_grec->push_back(LegoBoundaryEdge(edge, p_oldBoundary)); } } else { - boundaryList.push_back(LegoBEWithFloat(edge, p_oldBoundary, edge->DistanceToMidpoint(p_oldPosition)) + boundaryList.push_back( + LegoBEWithMidpoint(edge, p_oldBoundary, edge->DistanceToMidpoint(p_oldPosition)) ); boundarySet.insert(&boundaryList.back()); } @@ -827,10 +835,10 @@ MxResult LegoPathController::FUN_10048310( pathCtrlEdgeSet.erase(edge); } - if (!p_grec->GetBit1()) { + if (!p_grec->HasPath()) { while (pathCtrlEdgeSet.size() > 0) { - LegoBEWithFloat edgeWithFloat; - MxFloat local70 = 999999.0f; + LegoBEWithMidpoint edgeWithMidpoint; + MxFloat minDist = 999999.0f; boundarySetItA = boundarySetItB = boundarySet.begin(); @@ -855,19 +863,20 @@ MxResult LegoPathController::FUN_10048310( if (bOther == p_newBoundary) { shouldRemove = FALSE; - LegoBEWithFloat* pfs = *boundarySetItA; + LegoBEWithMidpoint* pfs = *boundarySetItA; assert(pfs); float dist; - if ((dist = pfs->m_edge->DistanceToMidpoint(p_newPosition) + pfs->m_unk0x0c) < local70) { - edgeWithFloat.m_edge = NULL; - local70 = dist; + if ((dist = pfs->m_edge->DistanceToMidpoint(p_newPosition) + pfs->m_distanceToMidpoint) < + minDist) { + edgeWithMidpoint.m_edge = NULL; + minDist = dist; // TODO: Match - if (dist < local14) { - local14 = dist; + if (dist < minDistance) { + minDistance = dist; p_grec->erase(p_grec->begin(), p_grec->end()); - p_grec->SetBit1(TRUE); + p_grec->SetPath(TRUE); do { p_grec->push_front(LegoBoundaryEdge(pfs->m_edge, pfs->m_boundary)); @@ -885,10 +894,10 @@ MxResult LegoPathController::FUN_10048310( shouldRemove = FALSE; float dist; - if ((dist = edge->DistanceBetweenMidpoints(*e) + (*boundarySetItA)->m_unk0x0c) < - local70) { - local70 = dist; - edgeWithFloat = LegoBEWithFloat(edge, bOther, *boundarySetItA, dist); + if ((dist = edge->DistanceBetweenMidpoints(*e) + + (*boundarySetItA)->m_distanceToMidpoint) < minDist) { + minDist = dist; + edgeWithMidpoint = LegoBEWithMidpoint(edge, bOther, *boundarySetItA, dist); } } } @@ -909,9 +918,9 @@ MxResult LegoPathController::FUN_10048310( } } - if (edgeWithFloat.m_edge != NULL) { - pathCtrlEdgeSet.erase(edgeWithFloat.m_edge); - boundaryList.push_back(edgeWithFloat); + if (edgeWithMidpoint.m_edge != NULL) { + pathCtrlEdgeSet.erase(edgeWithMidpoint.m_edge); + boundaryList.push_back(edgeWithMidpoint); boundarySet.insert(&boundaryList.back()); } else { @@ -920,7 +929,7 @@ MxResult LegoPathController::FUN_10048310( } } - if (p_grec->GetBit1()) { + if (p_grec->HasPath()) { if (p_grec->size() > 0) { LegoPathCtrlEdge* edge = p_grec->front().m_edge; @@ -941,8 +950,8 @@ MxResult LegoPathController::FUN_10048310( } } - if (p_param9 != NULL) { - *p_param9 = local14; + if (p_distance != NULL) { + *p_distance = minDistance; } return SUCCESS; @@ -953,20 +962,20 @@ MxResult LegoPathController::FUN_10048310( // FUNCTION: LEGO1 0x1004a240 // FUNCTION: BETA10 0x100b9160 -MxS32 LegoPathController::FUN_1004a240( +MxS32 LegoPathController::GetNextPathEdge( LegoPathEdgeContainer& p_grec, - Vector3& p_v1, - Vector3& p_v2, + Vector3& p_position, + Vector3& p_direction, float p_f1, LegoOrientedEdge*& p_edge, LegoPathBoundary*& p_boundary ) { if (p_grec.size() == 0) { - p_v1 = p_grec.m_position; - p_v2 = p_grec.m_direction; + p_position = p_grec.m_position; + p_direction = p_grec.m_direction; p_boundary = p_grec.m_boundary; - p_grec.SetBit1(FALSE); + p_grec.SetPath(FALSE); return 1; } @@ -975,28 +984,28 @@ MxS32 LegoPathController::FUN_1004a240( p_grec.pop_front(); Mx3DPointFloat vec; - p_v1 = *p_edge->CCWVertex(*p_boundary); - p_v1 -= *p_edge->CWVertex(*p_boundary); - p_v1 *= p_f1; - p_v1 += *p_edge->CWVertex(*p_boundary); + p_position = *p_edge->CCWVertex(*p_boundary); + p_position -= *p_edge->CWVertex(*p_boundary); + p_position *= p_f1; + p_position += *p_edge->CWVertex(*p_boundary); p_edge->GetFaceNormal(*p_boundary, vec); - p_v2.EqualsCross(*p_boundary->GetUp(), vec); + p_direction.EqualsCross(*p_boundary->GetUp(), vec); return 0; } // FUNCTION: LEGO1 0x1004a380 // FUNCTION: BETA10 0x100b957f -MxResult LegoPathController::FUN_1004a380( - Vector3& p_param1, - Vector3& p_param2, - Mx3DPointFloat* p_param3, +MxResult LegoPathController::FindIntersectionBoundary( + Vector3& p_location, + Vector3& p_direction, + Mx3DPointFloat* p_coefficients, LegoPathBoundary*& p_boundary, - MxFloat& p_param5 + MxFloat& p_apexParameter ) { - MxFloat param5 = p_param5; - Mx3DPointFloat local24; - MxU32 local8 = TRUE; + MxFloat originalApexParameter = p_apexParameter; + Mx3DPointFloat intersectionPoint; + MxU32 solutionNotFound = TRUE; for (MxS32 i = 0; i < m_numL; i++) { if (m_boundaries[i].m_flags & LegoPathBoundary::c_bit3) { @@ -1004,75 +1013,76 @@ MxResult LegoPathController::FUN_1004a380( } LegoPathBoundary* b = &m_boundaries[i]; - Mx4DPointFloat* unk0x14 = b->GetUp(); - float local28 = p_param3[0].Dot(p_param3[0], *unk0x14); + Mx4DPointFloat* up = b->GetUp(); + float coeffADotUp = p_coefficients[0].Dot(p_coefficients[0], *up); - if (local28 < 0.001 && local28 > -0.001) { + if (coeffADotUp < 0.001 && coeffADotUp > -0.001) { continue; } - float local2c = p_param3[1].Dot(p_param3[1], *unk0x14); - float local34 = p_param3[2].Dot(p_param3[2], *unk0x14) + unk0x14->index_operator(3); - float local3c = local2c * local2c - local34 * local28 * 4.0f; + float coeffBDotUp = p_coefficients[1].Dot(p_coefficients[1], *up); + float coeffCDotUp = p_coefficients[2].Dot(p_coefficients[2], *up) + up->index_operator(3); + float quadraticDiscriminant = coeffBDotUp * coeffBDotUp - coeffCDotUp * coeffADotUp * 4.0f; - if (local3c < -0.001) { + if (quadraticDiscriminant < -0.001) { continue; } - if (local3c < 0.0f) { - local3c = 0.0f; + if (quadraticDiscriminant < 0.0f) { + quadraticDiscriminant = 0.0f; } else { - local3c = sqrt(local3c); + quadraticDiscriminant = sqrt(quadraticDiscriminant); } - float local38 = (local3c - local2c) / (local28 * 2.0f); - float local44 = (-local3c - local2c) / (local28 * 2.0f); + float intersectionParameter = (quadraticDiscriminant - coeffBDotUp) / (coeffADotUp * 2.0f); + float alternativeIntersectionParameter = (-quadraticDiscriminant - coeffBDotUp) / (coeffADotUp * 2.0f); - if (!IsBetween(local38, 0.0f, param5)) { - if (IsBetween(local44, 0.0f, param5)) { - local38 = local44; + if (!IsBetween(intersectionParameter, 0.0f, originalApexParameter)) { + if (IsBetween(alternativeIntersectionParameter, 0.0f, originalApexParameter)) { + intersectionParameter = alternativeIntersectionParameter; } else { continue; } } - if (local8 || FUN_100c17a0(local38, p_param5, 0.0f, param5)) { - Mx3DPointFloat local58(p_param3[0]); + if (solutionNotFound || + BothSameComparison(intersectionParameter, p_apexParameter, 0.0f, originalApexParameter)) { + Mx3DPointFloat tSqrA(p_coefficients[0]); - local58 *= local38 * local38; - local24 = p_param3[1]; - local24 *= local38; - local24 += p_param3[2]; - local24 += local58; + tSqrA *= intersectionParameter * intersectionParameter; + intersectionPoint = p_coefficients[1]; + intersectionPoint *= intersectionParameter; + intersectionPoint += p_coefficients[2]; + intersectionPoint += tSqrA; assert(b->GetNumEdges() > 1); MxS32 j; for (j = b->GetNumEdges() - 1; j >= 0; j--) { - Mx4DPointFloat* local60 = b->GetEdgeNormal(j); + Mx4DPointFloat* edgeNormal = b->GetEdgeNormal(j); - if (local24.Dot(*local60, local24) + local60->index_operator(3) < -0.001) { + if (intersectionPoint.Dot(*edgeNormal, intersectionPoint) + edgeNormal->index_operator(3) < -0.001) { break; } } if (j < 0) { - Mx3DPointFloat local74(p_param1); - local74 -= local24; + Mx3DPointFloat direction(p_location); + direction -= intersectionPoint; - if (local74.Dot(local74, *unk0x14) >= 0.0f) { - p_param5 = local38; + if (direction.Dot(direction, *up) >= 0.0f) { + p_apexParameter = intersectionParameter; p_boundary = b; - local8 = FALSE; + solutionNotFound = FALSE; } } } } - if (local8) { - p_param5 = param5; + if (solutionNotFound) { + p_apexParameter = originalApexParameter; return FAILURE; } diff --git a/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp b/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp index 15cca7c4..4f40ace4 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp @@ -68,7 +68,7 @@ MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction, case c_h: { LegoHideAnimPresenter* presenter = m_world->GetHideAnimPresenter(); if (presenter != NULL) { - presenter->FUN_1006db40(p_data * 100); + presenter->ApplyVisibility(p_data * 100); } break; } diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index 931e01ce..969c6c11 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -119,7 +119,7 @@ void CarRace::ReadyWorld() { assert(m_hideAnim); LegoWorld::ReadyWorld(); - m_hideAnim->FUN_1006db40(0); + m_hideAnim->ApplyVisibility(0); MxDSAction action; action.SetAtomId(*g_jukeboxScript); diff --git a/LEGO1/lego/legoomni/src/race/jetskirace.cpp b/LEGO1/lego/legoomni/src/race/jetskirace.cpp index 147d8768..f16ee5a0 100644 --- a/LEGO1/lego/legoomni/src/race/jetskirace.cpp +++ b/LEGO1/lego/legoomni/src/race/jetskirace.cpp @@ -83,7 +83,7 @@ void JetskiRace::ReadyWorld() { assert(m_hideAnim); LegoWorld::ReadyWorld(); - m_hideAnim->FUN_1006db40(0); + m_hideAnim->ApplyVisibility(0); MxDSAction action; action.SetAtomId(*g_jukeboxScript); @@ -216,7 +216,7 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param) result = 1; } else if (m_playerLastPathStruct == 0xf) { - m_hideAnim->FUN_1006db40(m_playerLaps * 200 + 100); + m_hideAnim->ApplyVisibility(m_playerLaps * 200 + 100); result = 1; } diff --git a/LEGO1/lego/legoomni/src/race/legorace.cpp b/LEGO1/lego/legoomni/src/race/legorace.cpp index ea56a692..5f869095 100644 --- a/LEGO1/lego/legoomni/src/race/legorace.cpp +++ b/LEGO1/lego/legoomni/src/race/legorace.cpp @@ -116,19 +116,19 @@ void LegoRace::Enable(MxBool p_enable) // FUNCTION: LEGO1 0x10015f30 RaceState::RaceState() { - m_entries[0].m_id = 1; + m_entries[0].m_id = LegoActor::c_pepper; m_entries[0].m_lastScore = 0; m_entries[0].m_score = 0; - m_entries[1].m_id = 2; + m_entries[1].m_id = LegoActor::c_mama; m_entries[1].m_lastScore = 0; m_entries[1].m_score = 0; - m_entries[2].m_id = 3; + m_entries[2].m_id = LegoActor::c_papa; m_entries[2].m_lastScore = 0; m_entries[2].m_score = 0; - m_entries[3].m_id = 4; + m_entries[3].m_id = LegoActor::c_nick; m_entries[3].m_lastScore = 0; m_entries[3].m_score = 0; - m_entries[4].m_id = 5; + m_entries[4].m_id = LegoActor::c_laura; m_entries[4].m_lastScore = 0; m_entries[4].m_score = 0; m_state = RaceState::e_carrace; diff --git a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp index 6019ba17..d76bc21f 100644 --- a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp +++ b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp @@ -25,9 +25,9 @@ LegoRaceActor::LegoRaceActor() // FUNCTION: LEGO1 0x10014750 // FUNCTION: BETA10 0x100c9bba -MxS32 LegoRaceActor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) +MxS32 LegoRaceActor::CheckIntersections(Vector3& p_rayOrigin, Vector3& p_rayEnd, Vector3& p_intersectionPoint) { - MxS32 result = LegoPathActor::VTable0x68(p_v1, p_v2, p_v3); + MxS32 result = LegoPathActor::CheckIntersections(p_rayOrigin, p_rayEnd, p_intersectionPoint); if (m_userNavFlag && result) { MxLong time = Timer()->GetTime(); @@ -46,20 +46,20 @@ MxS32 LegoRaceActor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) // FUNCTION: LEGO1 0x100147f0 // FUNCTION: BETA10 0x100c9c93 -MxU32 LegoRaceActor::VTable0x90(float p_time, Matrix4& p_transform) +MxU32 LegoRaceActor::StepState(float p_time, Matrix4& p_transform) { - // Note: Code duplication with LegoExtraActor::VTable0x90 + // Note: Code duplication with LegoExtraActor::StepState switch (m_actorState) { case c_initial: - case c_one: + case c_ready: return TRUE; - case c_two: + case c_hit: m_unk0x08 = p_time + 2000.0f; - m_actorState = c_three; - m_actorTime += (p_time - m_lastTime) * m_worldSpeed; - m_lastTime = p_time; + m_actorState = c_hitAnimation; + m_actorTime += (p_time - m_transformTime) * m_worldSpeed; + m_transformTime = p_time; return FALSE; - case c_three: + case c_hitAnimation: assert(!m_userNavFlag); Vector3 positionRef(p_transform[3]); @@ -73,10 +73,10 @@ MxU32 LegoRaceActor::VTable0x90(float p_time, Matrix4& p_transform) p_transform.RotateX(0.6); positionRef = position; - m_actorTime += (p_time - m_lastTime) * m_worldSpeed; - m_lastTime = p_time; + m_actorTime += (p_time - m_transformTime) * m_worldSpeed; + m_transformTime = p_time; - VTable0x74(p_transform); + ApplyTransform(p_transform); return FALSE; } else { @@ -111,7 +111,7 @@ MxResult LegoRaceActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) roi->SetLocal2World(matr); - p_actor->SetActorState(c_two); + p_actor->SetActorState(c_hit); } } diff --git a/LEGO1/lego/legoomni/src/race/legoracemap.cpp b/LEGO1/lego/legoomni/src/race/legoracemap.cpp index 9637114d..cbc1cbb2 100644 --- a/LEGO1/lego/legoomni/src/race/legoracemap.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracemap.cpp @@ -15,7 +15,7 @@ DECOMP_SIZE_ASSERT(LegoRaceMap, 0x1b4) // FUNCTION: BETA10 0x100ca2c0 LegoRaceMap::LegoRaceMap() { - m_unk0x08 = FALSE; + m_mapEnabled = FALSE; m_stillPresenter = NULL; m_Map_Ctl = 0; ControlManager()->Register(this); @@ -54,42 +54,42 @@ void LegoRaceMap::ParseAction(char* p_extra) if (KeyValueStringParse(value, g_mapGeometry, p_extra)) { char* token = strtok(value, g_parseExtraTokens); if (token != NULL) { - m_unk0x14 = atof(token); + m_worldXOffset = atof(token); } token = strtok(NULL, g_parseExtraTokens); if (token != NULL) { - m_unk0x18 = atof(token); + m_worldXScale = atof(token); } token = strtok(NULL, g_parseExtraTokens); if (token != NULL) { - m_unk0x1c = atof(token); + m_worldZOffset = atof(token); } token = strtok(NULL, g_parseExtraTokens); if (token != NULL) { - m_unk0x20 = atof(token); + m_worldZScale = atof(token); } token = strtok(NULL, g_parseExtraTokens); if (token != NULL) { - m_unk0x24 = atof(token); + m_screenXScale = atof(token); } token = strtok(NULL, g_parseExtraTokens); if (token != NULL) { - m_unk0x28 = atof(token); + m_screenYScale = atof(token); } token = strtok(NULL, g_parseExtraTokens); if (token != NULL) { - m_unk0x2c = atof(token); + m_screenXOffset = atof(token); } token = strtok(NULL, g_parseExtraTokens); if (token != NULL) { - m_unk0x30 = atof(token); + m_screenYOffset = atof(token); } } @@ -106,13 +106,13 @@ void LegoRaceMap::ParseAction(char* p_extra) // FUNCTION: LEGO1 0x1005d4b0 // FUNCTION: BETA10 0x100ca849 -void LegoRaceMap::FUN_1005d4b0() +void LegoRaceMap::UpdateMapLocatorPosition() { - if (m_unk0x08) { - short xPos = (GetWorldPosition()[0] - m_unk0x14) / m_unk0x18 * m_unk0x24; - short yPos = (GetWorldPosition()[2] - m_unk0x1c) / m_unk0x20 * m_unk0x28; + if (m_mapEnabled) { + short xPos = (GetWorldPosition()[0] - m_worldXOffset) / m_worldXScale * m_screenXScale; + short yPos = (GetWorldPosition()[2] - m_worldZOffset) / m_worldZScale * m_screenYScale; - m_stillPresenter->SetPosition(xPos + m_unk0x2c, m_unk0x30 - yPos); + m_stillPresenter->SetPosition(xPos + m_screenXOffset, m_screenYOffset - yPos); } } @@ -130,12 +130,12 @@ MxLong LegoRaceMap::Notify(MxParam& p_param) m_Map_Ctl->GetAction()->GetObjectId() == ((LegoControlManagerNotificationParam&) p_param).m_clickedObjectId) { if (((LegoControlManagerNotificationParam&) p_param).m_enabledChild == 1) { - m_unk0x08 = TRUE; - FUN_1005d4b0(); + m_mapEnabled = TRUE; + UpdateMapLocatorPosition(); m_stillPresenter->Enable(TRUE); } else { - m_unk0x08 = FALSE; + m_mapEnabled = FALSE; m_stillPresenter->Enable(FALSE); } } diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index db3700aa..8f747635 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -174,7 +174,7 @@ MxLong g_timeLastJetskiSoundPlayed = 0; // FUNCTION: BETA10 0x100cad10 LegoRaceCar::LegoRaceCar() { - m_userState = 0; + m_kickState = LEGORACECAR_NONE; m_skelKick1Anim = 0; m_skelKick2Anim = 0; m_unk0x5c.Clear(); @@ -304,11 +304,11 @@ void LegoRaceCar::KickCamera(float p_param) LegoAnimActorStruct* a; // called `a` in BETA10 float deltaTime; - if (m_userState == LEGORACECAR_KICK1) { + if (m_kickState == LEGORACECAR_KICK1) { a = m_skelKick1Anim; } else { - assert(m_userState == LEGORACECAR_KICK2); + assert(m_kickState == LEGORACECAR_KICK2); a = m_skelKick2Anim; } @@ -318,7 +318,7 @@ void LegoRaceCar::KickCamera(float p_param) deltaTime = p_param - m_kickStart; if (a->GetDuration() <= deltaTime || deltaTime < 0.0) { - if (m_userState == LEGORACECAR_KICK1) { + if (m_kickState == LEGORACECAR_KICK1) { LegoOrientedEdge** edges = m_kick1B->GetEdges(); m_destEdge = edges[2]; m_boundary = m_kick1B; @@ -329,7 +329,7 @@ void LegoRaceCar::KickCamera(float p_param) m_boundary = m_kick2B; } - m_userState = LEGORACECAR_UNKNOWN_0; + m_kickState = LEGORACECAR_NONE; } else if (a->GetAnimTreePtr()->GetCamAnim()) { MxMatrix transformationMatrix; @@ -373,12 +373,12 @@ MxU32 LegoRaceCar::HandleSkeletonKicks(float p_param1) for (MxS32 i = 0; i < sizeOfArray(g_skeletonKickPhases); i++) { if (m_boundary == current->m_edgeRef->m_b && current->m_lower <= skeletonCurAnimPhase && skeletonCurAnimPhase <= current->m_upper) { - m_userState = current->m_userState; + m_kickState = current->m_kickState; } current = ¤t[1]; } - if (m_userState != LEGORACECAR_KICK1 && m_userState != LEGORACECAR_KICK2) { + if (m_kickState != LEGORACECAR_KICK1 && m_kickState != LEGORACECAR_KICK2) { MxTrace( // STRING: BETA10 0x101f64c8 "Got kicked in boundary %s %d %g:%g %g\n", @@ -401,21 +401,21 @@ MxU32 LegoRaceCar::HandleSkeletonKicks(float p_param1) // FUNCTION: BETA10 0x100cb88a void LegoRaceCar::Animate(float p_time) { - if (m_userNavFlag && (m_userState == LEGORACECAR_KICK1 || m_userState == LEGORACECAR_KICK2)) { + if (m_userNavFlag && (m_kickState == LEGORACECAR_KICK1 || m_kickState == LEGORACECAR_KICK2)) { KickCamera(p_time); return; } LegoCarRaceActor::Animate(p_time); - if (m_userNavFlag && m_userState == LEGORACECAR_UNKNOWN_1) { + if (m_userNavFlag && m_kickState == LEGORACECAR_NEAR_SKELETON) { if (HandleSkeletonKicks(p_time)) { return; } } if (LegoCarRaceActor::m_animState == 1) { - FUN_1005d4b0(); + UpdateMapLocatorPosition(); if (!m_userNavFlag) { FUN_10080590(p_time); @@ -475,7 +475,7 @@ MxResult LegoRaceCar::HitActor(LegoPathActor* p_actor, MxBool p_bool) Vector3(matr[3]) += g_hitOffset; roi->SetLocal2World(matr); - p_actor->SetActorState(c_two); + p_actor->SetActorState(c_hit); } if (m_userNavFlag) { @@ -538,36 +538,36 @@ MxResult LegoRaceCar::HitActor(LegoPathActor* p_actor, MxBool p_bool) // FUNCTION: LEGO1 0x10013600 // FUNCTION: BETA10 0x100cbe60 -MxResult LegoRaceCar::VTable0x9c() +MxResult LegoRaceCar::CalculateSpline() { MxResult result; if (m_userNavFlag) { - result = LegoCarRaceActor::VTable0x9c(); + result = LegoCarRaceActor::CalculateSpline(); if (m_boundary) { - MxS32 bVar2 = 0; + MxS32 onSkeletonBoundary = FALSE; for (MxS32 i = 0; i < sizeOfArray(g_skBMap); i++) { assert(g_skBMap[i].m_b); if (m_boundary == g_skBMap[i].m_b) { - bVar2 = 1; + onSkeletonBoundary = TRUE; break; } } - if (m_userState == LEGORACECAR_UNKNOWN_1) { - if (!bVar2) { - m_userState = LEGORACECAR_UNKNOWN_0; + if (m_kickState == LEGORACECAR_NEAR_SKELETON) { + if (!onSkeletonBoundary) { + m_kickState = LEGORACECAR_NONE; } } else { - m_userState = LEGORACECAR_UNKNOWN_1; + m_kickState = LEGORACECAR_NEAR_SKELETON; } } } else { - result = LegoCarRaceActor::VTable0x9c(); + result = LegoCarRaceActor::CalculateSpline(); } return result; @@ -598,7 +598,7 @@ void LegoJetski::SetWorldSpeed(MxFloat p_worldSpeed) // FUNCTION: LEGO1 0x100136f0 // FUNCTION: BETA10 0x100cc01a -void LegoJetski::FUN_100136f0(float p_worldSpeed) +void LegoJetski::SetMaxLinearVelocity(float p_worldSpeed) { if (p_worldSpeed < 0) { LegoCarRaceActor::m_animState = 2; @@ -617,7 +617,7 @@ void LegoJetski::Animate(float p_time) LegoJetskiRaceActor::Animate(p_time); if (LegoCarRaceActor::m_animState == 1) { - FUN_1005d4b0(); + UpdateMapLocatorPosition(); if (!m_userNavFlag) { FUN_10080590(p_time); @@ -692,7 +692,7 @@ MxResult LegoJetski::HitActor(LegoPathActor* p_actor, MxBool p_bool) Vector3(matr[3]) += g_hitOffset; roi->SetLocal2World(matr); - p_actor->SetActorState(c_two); + p_actor->SetActorState(c_hit); } if (m_userNavFlag) { diff --git a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp index 409ad137..0269bf37 100644 --- a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp @@ -52,9 +52,9 @@ LegoCarRaceActor::LegoCarRaceActor() m_unk0x10 = 0.65f; m_unk0x14 = 0.03f; m_unk0x18 = 0.6f; - m_unk0x140 = 0.1f; - m_unk0x150 = -5.0f; - m_unk0x148 = 1; + m_wallHitDirectionFactor = 0.1f; + m_linearRotationRatio = -5.0f; + m_canRotate = 1; VariableTable()->SetVariable(g_fuel, "0.8"); } @@ -119,7 +119,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg Mx3DPointFloat destEdgeUnknownVector; Mx3DPointFloat crossProduct; - if (m_actorState == c_one) { + if (m_actorState == c_ready) { m_boundary = NULL; // Not sure where the upper bound of 11 comes from, the underlying array has a size of 16 @@ -133,7 +133,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg assert(m_boundary); m_actorState = c_initial; - m_unk0x7c = 0; + m_traveledDistance = 0; if (m_userNavFlag) { NavController()->SetLinearVel(m_worldSpeed); @@ -146,7 +146,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg else { for (MxS32 i = 0; i < 11; i += 2) { if (LegoPathController::GetControlEdgeA(i) == p_edge) { - m_actorState = c_one; + m_actorState = c_ready; if (m_worldSpeed < g_unk0x100f7aec) { m_worldSpeed = g_unk0x100f7aec; @@ -158,9 +158,9 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg } } - if (m_actorState == c_one) { + if (m_actorState == c_ready) { if (m_userNavFlag) { - m_unk0xe4 = 0.5f; + m_destScale = 0.5f; } // variable names verified by BETA10 @@ -168,7 +168,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg Vector3* v2 = m_destEdge->CWVertex(*m_boundary); assert(v1 && v2); - LERP3(pointUnknown, *v1, *v2, m_unk0xe4); + LERP3(pointUnknown, *v1, *v2, m_destScale); m_destEdge->GetFaceNormal(*m_boundary, destEdgeUnknownVector); @@ -185,14 +185,14 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg crossProduct *= 5.0f; MxResult callResult = - VTable0x80(Vector3(m_roi->GetWorldPosition()), worldDirection, pointUnknown, crossProduct); + SetSpline(Vector3(m_roi->GetWorldPosition()), worldDirection, pointUnknown, crossProduct); if (callResult) { - m_unk0x7c = 0; + m_traveledDistance = 0; return 0; } else { - m_unk0x7c = 0; + m_traveledDistance = 0; #ifdef BETA10 assert(0); #endif @@ -217,7 +217,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg // FUNCTION: BETA10 0x100cdb3c void LegoCarRaceActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoOrientedEdge*& p_edge, float& p_unk0xe4) { - LegoPathActor::SwitchBoundary(m_boundary, m_destEdge, m_unk0xe4); + LegoPathActor::SwitchBoundary(m_boundary, m_destEdge, m_destScale); } // FUNCTION: LEGO1 0x10080b70 @@ -230,7 +230,7 @@ void LegoCarRaceActor::Animate(float p_time) if (SDL_strcasecmp(value, g_racing) == 0) { m_animState = 1; - m_lastTime = p_time - 1.0f; + m_transformTime = p_time - 1.0f; m_unk0x1c = p_time; } } @@ -242,14 +242,14 @@ void LegoCarRaceActor::Animate(float p_time) // FUNCTION: LEGO1 0x10080be0 // FUNCTION: BETA10 0x100cdc54 -MxResult LegoCarRaceActor::VTable0x9c() +MxResult LegoCarRaceActor::CalculateSpline() { LegoOrientedEdge* d = m_destEdge; if (VTable0x1c(m_boundary, m_destEdge)) { LegoPathBoundary* b = m_boundary; - SwitchBoundary(m_boundary, m_destEdge, m_unk0xe4); + SwitchBoundary(m_boundary, m_destEdge, m_destScale); assert(m_boundary && m_destEdge); // variable names verified by BETA10 @@ -258,7 +258,7 @@ MxResult LegoCarRaceActor::VTable0x9c() assert(v1 && v2); Mx3DPointFloat point1; - LERP3(point1, *v1, *v2, m_unk0xe4); + LERP3(point1, *v1, *v2, m_destScale); Mx3DPointFloat point2; Mx3DPointFloat point3; @@ -277,7 +277,7 @@ MxResult LegoCarRaceActor::VTable0x9c() point4 *= 5.0f; point5 *= 5.0f; - MxResult res = VTable0x80(m_roi->GetWorldPosition(), point4, point1, point5); + MxResult res = SetSpline(m_roi->GetWorldPosition(), point4, point1, point5); #ifdef BETA10 if (res) { @@ -286,7 +286,7 @@ MxResult LegoCarRaceActor::VTable0x9c() } #endif - m_unk0x7c = 0; + m_traveledDistance = 0; } return SUCCESS; @@ -299,7 +299,7 @@ LegoJetskiRaceActor::LegoJetskiRaceActor() m_unk0x10 = 0.95f; m_unk0x14 = 0.04f; m_unk0x18 = 0.5f; - m_unk0x150 = 1.5f; + m_linearRotationRatio = 1.5f; } // FUNCTION: LEGO1 0x10081120 @@ -315,7 +315,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ Vector3* v1 = NULL; Vector3* v2 = NULL; - if (m_actorState == c_one) { + if (m_actorState == c_ready) { if (m_destEdge == LegoPathController::GetControlEdgeA(13)) { m_boundary = (LegoPathBoundary*) m_destEdge->OtherFace(LegoPathController::GetControlBoundaryA(13)); } @@ -324,7 +324,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ } m_actorState = c_initial; - m_unk0x7c = 0; + m_traveledDistance = 0; if (m_userNavFlag) { NavController()->SetLinearVel(m_worldSpeed); @@ -336,7 +336,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ } else { if (p_edge == LegoPathController::GetControlEdgeA(12)) { - m_actorState = c_one; + m_actorState = c_ready; if (m_worldSpeed < g_unk0x100da044) { m_worldSpeed = g_unk0x100da044; @@ -346,7 +346,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ m_boundary = LegoPathController::GetControlBoundaryA(13); } else if (p_edge == LegoPathController::GetControlEdgeA(14)) { - m_actorState = c_one; + m_actorState = c_ready; if (m_worldSpeed < g_unk0x100da044) { m_worldSpeed = g_unk0x100da044; @@ -356,16 +356,16 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ m_boundary = LegoPathController::GetControlBoundaryA(15); } - if (m_actorState == c_one) { + if (m_actorState == c_ready) { if (m_userNavFlag) { - m_unk0xe4 = 0.5f; + m_destScale = 0.5f; } v1 = m_destEdge->CCWVertex(*m_boundary); v2 = m_destEdge->CWVertex(*m_boundary); assert(v1 && v2); - LERP3(a, *v1, *v2, m_unk0xe4); + LERP3(a, *v1, *v2, m_destScale); m_destEdge->GetFaceNormal(*m_boundary, bbb); c.EqualsCross(bbb, *m_boundary->GetUp()); @@ -377,9 +377,9 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ worldDirection *= -1.0f; } - if (VTable0x80(m_roi->GetWorldPosition(), worldDirection, a, c)) { + if (SetSpline(m_roi->GetWorldPosition(), worldDirection, a, c)) { #ifndef BETA10 - m_unk0x7c = 0; + m_traveledDistance = 0; return 0; #else assert(0); @@ -387,7 +387,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ #endif } - m_unk0x7c = 0; + m_traveledDistance = 0; return 0; } else { @@ -403,11 +403,11 @@ void LegoJetskiRaceActor::Animate(float p_time) const LegoChar* raceState = VariableTable()->GetVariable(g_raceState); if (!SDL_strcasecmp(raceState, g_racing)) { m_animState = 1; - m_lastTime = p_time - 1.0f; + m_transformTime = p_time - 1.0f; m_unk0x1c = p_time; } else if (!m_userNavFlag) { - LegoAnimActor::Animate(m_lastTime + 1.0f); + LegoAnimActor::Animate(m_transformTime + 1.0f); } } @@ -418,13 +418,13 @@ void LegoJetskiRaceActor::Animate(float p_time) // FUNCTION: LEGO1 0x10081840 // FUNCTION: BETA10 0x100cf680 -MxU32 LegoCarRaceActor::VTable0x6c( +MxU32 LegoCarRaceActor::CheckPresenterAndActorIntersections( LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint ) { // STRING: LEGO1 0x100f7af4 @@ -433,7 +433,7 @@ MxU32 LegoCarRaceActor::VTable0x6c( LegoAnimPresenterSet& presenters = p_boundary->GetPresenters(); for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) { - if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) { + if ((*itap)->Intersect(p_rayOrigin, p_rayDirection, p_rayLength, p_radius, p_intersectionPoint)) { return 1; } } @@ -457,8 +457,14 @@ MxU32 LegoCarRaceActor::VTable0x6c( LegoROI* firstROI = (LegoROI*) co->front(); - if (firstROI - ->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) { + if (firstROI->Intersect( + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint, + m_collideBox && actor->GetCollideBox() + )) { HitActor(actor, TRUE); if (actor->HitActor(this, FALSE) < 0) { @@ -471,8 +477,14 @@ MxU32 LegoCarRaceActor::VTable0x6c( LegoROI* lastROI = (LegoROI*) co->back(); - if (lastROI - ->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) { + if (lastROI->Intersect( + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint, + m_collideBox && actor->GetCollideBox() + )) { HitActor(actor, TRUE); if (actor->HitActor(this, FALSE) < 0) { @@ -485,7 +497,14 @@ MxU32 LegoCarRaceActor::VTable0x6c( } } else { - if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) { + if (roi->Intersect( + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint, + m_collideBox && actor->GetCollideBox() + )) { HitActor(actor, TRUE); if (actor->HitActor(this, FALSE) < 0) { @@ -505,19 +524,19 @@ MxU32 LegoCarRaceActor::VTable0x6c( } // FUNCTION: LEGO1 0x10081fd0 -MxU32 LegoJetskiRaceActor::VTable0x6c( +MxU32 LegoJetskiRaceActor::CheckPresenterAndActorIntersections( LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint ) { LegoAnimPresenterSet& presenters = p_boundary->GetPresenters(); for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) { - if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) { + if ((*itap)->Intersect(p_rayOrigin, p_rayDirection, p_rayLength, p_radius, p_intersectionPoint)) { return 1; } } @@ -533,7 +552,14 @@ MxU32 LegoJetskiRaceActor::VTable0x6c( LegoROI* roi = actor->GetROI(); if (roi != NULL && (roi->GetVisibility() || actor->GetCameraFlag())) { - if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) { + if (roi->Intersect( + p_rayOrigin, + p_rayDirection, + p_rayLength, + p_radius, + p_intersectionPoint, + m_collideBox && actor->GetCollideBox() + )) { HitActor(actor, TRUE); if (actor->HitActor(this, FALSE) < 0) { diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index ff2f79f7..8eb902cd 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -57,21 +57,21 @@ void LegoAnimPresenter::Init() m_roiMapSize = 0; m_managedActors = NULL; m_sceneROIs = NULL; - m_unk0x78 = NULL; + m_transform = NULL; m_flags = 0; - m_unk0xa8.Clear(); - m_unk0xa4 = 0; + m_centerPoint.Clear(); + m_boundingRadius = 0; m_currentWorld = NULL; - m_unk0x95 = FALSE; + m_animationFinished = FALSE; m_worldId = -1; m_substMap = NULL; m_worldAtom.Clear(); - m_unk0x9c = 0; - m_unk0x8c = NULL; - m_unk0x90 = NULL; - m_unk0x94 = 0; - m_unk0x96 = TRUE; - m_unk0xa0 = NULL; + m_roiTransformApplied = 0; + m_ptAtCamROI = NULL; + m_ptAtCamNames = NULL; + m_ptAtCamCount = 0; + m_localActors = TRUE; + m_roiTransform = NULL; } // FUNCTION: LEGO1 0x10068770 @@ -94,12 +94,12 @@ void LegoAnimPresenter::Destroy(MxBool p_fromDestructor) } if (m_managedActors != NULL) { - FUN_1006aa60(); + ReleaseManagedActors(); delete m_managedActors; } - if (m_unk0x78 != NULL) { - delete m_unk0x78; + if (m_transform != NULL) { + delete m_transform; } if (m_substMap != NULL) { @@ -115,22 +115,22 @@ void LegoAnimPresenter::Destroy(MxBool p_fromDestructor) delete m_substMap; } - if (m_unk0x90 != NULL) { - for (MxS32 i = 0; i < m_unk0x94; i++) { - if (m_unk0x90[i] != NULL) { - delete[] m_unk0x90[i]; + if (m_ptAtCamNames != NULL) { + for (MxS32 i = 0; i < m_ptAtCamCount; i++) { + if (m_ptAtCamNames[i] != NULL) { + delete[] m_ptAtCamNames[i]; } } - delete[] m_unk0x90; + delete[] m_ptAtCamNames; } - if (m_unk0x8c != NULL) { - delete[] m_unk0x8c; + if (m_ptAtCamROI != NULL) { + delete[] m_ptAtCamROI; } - if (m_unk0xa0 != NULL) { - delete m_unk0xa0; + if (m_roiTransform != NULL) { + delete m_roiTransform; } Init(); @@ -153,16 +153,16 @@ MxResult LegoAnimPresenter::CreateAnim(MxStreamChunk* p_chunk) if (storage.Read(&magicSig, sizeof(MxS32)) != SUCCESS || magicSig != 0x11) { goto done; } - if (storage.Read(&m_unk0xa4, sizeof(float)) != SUCCESS) { + if (storage.Read(&m_boundingRadius, sizeof(float)) != SUCCESS) { goto done; } - if (storage.Read(&m_unk0xa8[0], sizeof(float)) != SUCCESS) { + if (storage.Read(&m_centerPoint[0], sizeof(float)) != SUCCESS) { goto done; } - if (storage.Read(&m_unk0xa8[1], sizeof(float)) != SUCCESS) { + if (storage.Read(&m_centerPoint[1], sizeof(float)) != SUCCESS) { goto done; } - if (storage.Read(&m_unk0xa8[2], sizeof(float)) != SUCCESS) { + if (storage.Read(&m_centerPoint[2], sizeof(float)) != SUCCESS) { goto done; } if (storage.Read(&parseScene, sizeof(LegoS32)) != SUCCESS) { @@ -193,24 +193,24 @@ MxResult LegoAnimPresenter::CreateAnim(MxStreamChunk* p_chunk) } // FUNCTION: LEGO1 0x10069150 -LegoChar* LegoAnimPresenter::FUN_10069150(const LegoChar* p_und1) +LegoChar* LegoAnimPresenter::GetActorName(const LegoChar* p_name) { LegoChar* str; - if (LegoCharacterManager::IsActor(p_und1 + 1)) { - str = new LegoChar[strlen(p_und1)]; + if (LegoCharacterManager::IsActor(p_name + 1)) { + str = new LegoChar[strlen(p_name)]; if (str != NULL) { - strcpy(str, p_und1 + 1); + strcpy(str, p_name + 1); } } else { LegoChar buffer[32]; sprintf(buffer, "%d", m_action->GetUnknown24()); - str = new LegoChar[strlen(p_und1) + strlen(buffer) + strlen(GetActionObjectName()) + 1]; + str = new LegoChar[strlen(p_name) + strlen(buffer) + strlen(GetActionObjectName()) + 1]; if (str != NULL) { - strcpy(str, p_und1); + strcpy(str, p_name); strcat(str, buffer); strcat(str, GetActionObjectName()); } @@ -220,7 +220,7 @@ LegoChar* LegoAnimPresenter::FUN_10069150(const LegoChar* p_und1) } // FUNCTION: LEGO1 0x100692b0 -void LegoAnimPresenter::FUN_100692b0() +void LegoAnimPresenter::CreateManagedActors() { m_managedActors = new LegoROIList(); @@ -232,7 +232,7 @@ void LegoAnimPresenter::FUN_100692b0() LegoU32 actorType = m_anim->GetActorType(i); LegoROI* roi = NULL; - if (actorType == LegoAnimActorEntry::e_actorType2) { + if (actorType == LegoAnimActorEntry::e_managedLegoActor) { LegoChar* src; if (str[0] == '*') { src = str + 1; @@ -247,44 +247,44 @@ void LegoAnimPresenter::FUN_100692b0() roi->SetVisibility(FALSE); } } - else if (actorType == LegoAnimActorEntry::e_actorType4) { + else if (actorType == LegoAnimActorEntry::e_managedInvisibleRoi) { LegoChar* baseName = new LegoChar[strlen(str)]; strcpy(baseName, str + 1); SDL_strlwr(baseName); - LegoChar* und = FUN_10069150(str); - roi = CharacterManager()->FUN_10085a80(und, baseName, TRUE); + LegoChar* roiName = GetActorName(str); + roi = CharacterManager()->FUN_10085a80(roiName, baseName, TRUE); if (roi != NULL) { roi->SetVisibility(FALSE); } delete[] baseName; - delete[] und; + delete[] roiName; } - else if (actorType == LegoAnimActorEntry::e_actorType3) { + else if (actorType == LegoAnimActorEntry::e_managedInvisibleRoiTrimmed) { LegoChar* lodName = new LegoChar[strlen(str)]; strcpy(lodName, str + 1); - for (LegoChar* i = &lodName[strlen(lodName) - 1]; i > lodName; i--) { - if ((*i < '0' || *i > '9') && *i != '_') { + for (LegoChar* c = &lodName[strlen(lodName) - 1]; c > lodName; c--) { + if ((*c < '0' || *c > '9') && *c != '_') { break; } - *i = '\0'; + *c = '\0'; } SDL_strlwr(lodName); - LegoChar* und = FUN_10069150(str); - roi = CharacterManager()->CreateAutoROI(und, lodName, TRUE); + LegoChar* roiName = GetActorName(str); + roi = CharacterManager()->CreateAutoROI(roiName, lodName, TRUE); if (roi != NULL) { roi->SetVisibility(FALSE); } delete[] lodName; - delete[] und; + delete[] roiName; } if (roi != NULL) { @@ -298,7 +298,7 @@ void LegoAnimPresenter::FUN_100692b0() // FUNCTION: LEGO1 0x100695c0 // FUNCTION: BETA10 0x1004f359 -void LegoAnimPresenter::FUN_100695c0() +void LegoAnimPresenter::CreateSceneROIs() { m_sceneROIs = new LegoROIList(); @@ -307,10 +307,10 @@ void LegoAnimPresenter::FUN_100695c0() LegoU32 numActors = m_anim->GetNumActors(); for (LegoU32 i = 0; i < numActors; i++) { - if (FUN_100698b0(rois, m_anim->GetActorName(i)) == FALSE) { + if (AppendROIToScene(rois, m_anim->GetActorName(i)) == FALSE) { LegoU32 actorType = m_anim->GetActorType(i); - if (actorType == LegoAnimActorEntry::e_actorType5 || actorType == LegoAnimActorEntry::e_actorType6) { + if (actorType == LegoAnimActorEntry::e_sceneRoi1 || actorType == LegoAnimActorEntry::e_sceneRoi2) { LegoChar lodName[256]; const LegoChar* actorName = m_anim->GetActorName(i); @@ -324,7 +324,7 @@ void LegoAnimPresenter::FUN_100695c0() SDL_strlwr(lodName); CharacterManager()->CreateAutoROI(actorName, lodName, FALSE); - FUN_100698b0(rois, actorName); + AppendROIToScene(rois, actorName); } } } @@ -359,13 +359,13 @@ LegoChar* LegoAnimPresenter::GetVariableOrIdentity(const LegoChar* p_varName, co } // FUNCTION: LEGO1 0x100698b0 -LegoBool LegoAnimPresenter::FUN_100698b0(const CompoundObject& p_rois, const LegoChar* p_und2) +LegoBool LegoAnimPresenter::AppendROIToScene(const CompoundObject& p_rois, const LegoChar* p_varName) { LegoBool result = FALSE; LegoChar* str; - if (*(str = GetVariableOrIdentity(p_und2, NULL)) == '*') { - LegoChar* tmp = FUN_10069150(str); + if (*(str = GetVariableOrIdentity(p_varName, NULL)) == '*') { + LegoChar* tmp = GetActorName(str); delete[] str; str = tmp; } @@ -410,12 +410,12 @@ LegoROI* LegoAnimPresenter::FindROI(const LegoChar* p_name) } // FUNCTION: LEGO1 0x10069b10 -void LegoAnimPresenter::FUN_10069b10() +void LegoAnimPresenter::BuildROIMap() { LegoAnimStructMap anims; - if (m_unk0x8c != NULL) { - memset(m_unk0x8c, 0, m_unk0x94 * sizeof(*m_unk0x8c)); + if (m_ptAtCamROI != NULL) { + memset(m_ptAtCamROI, 0, m_ptAtCamCount * sizeof(*m_ptAtCamROI)); } UpdateStructMapAndROIIndex(anims, m_anim->GetRoot(), NULL); @@ -434,10 +434,10 @@ void LegoAnimPresenter::FUN_10069b10() m_roiMap[index] = (*it).second.m_roi; if (m_roiMap[index]->GetName() != NULL) { - for (MxS32 i = 0; i < m_unk0x94; i++) { - if (m_unk0x8c[i] == NULL && m_unk0x90[i] != NULL) { - if (!SDL_strcasecmp(m_unk0x90[i], m_roiMap[index]->GetName())) { - m_unk0x8c[i] = m_roiMap[index]; + for (MxS32 i = 0; i < m_ptAtCamCount; i++) { + if (m_ptAtCamROI[i] == NULL && m_ptAtCamNames[i] != NULL) { + if (!SDL_strcasecmp(m_ptAtCamNames[i], m_roiMap[index]->GetName())) { + m_ptAtCamROI[i] = m_roiMap[index]; break; } } @@ -461,7 +461,7 @@ void LegoAnimPresenter::UpdateStructMapAndROIIndex(LegoAnimStructMap& p_map, Leg if (name != NULL && *name != '-') { if (*name == '*') { - name = und2 = FUN_10069150(name); + name = und2 = GetActorName(name); } und = GetVariableOrIdentity(name, p_roi != NULL ? p_roi->GetName() : NULL); @@ -506,13 +506,13 @@ void LegoAnimPresenter::UpdateStructMapAndROIIndex(LegoAnimStructMap& p_map, Leg void LegoAnimPresenter::UpdateStructMapAndROIIndexForNode( LegoAnimStructMap& p_map, LegoAnimNodeData* p_data, - const LegoChar* p_und, + const LegoChar* p_key, LegoROI* p_roi ) { LegoAnimStructMap::iterator it; - it = p_map.find(p_und); + it = p_map.find(p_key); if (it == p_map.end()) { LegoAnimStruct animStruct; animStruct.m_index = p_map.size() + 1; @@ -520,10 +520,10 @@ void LegoAnimPresenter::UpdateStructMapAndROIIndexForNode( p_data->SetROIIndex(animStruct.m_index); - LegoChar* und = new LegoChar[strlen(p_und) + 1]; - strcpy(und, p_und); + LegoChar* key = new LegoChar[strlen(p_key) + 1]; + strcpy(key, p_key); - p_map[und] = animStruct; + p_map[key] = animStruct; } else { p_data->SetROIIndex((*it).second.m_index); @@ -532,7 +532,7 @@ void LegoAnimPresenter::UpdateStructMapAndROIIndexForNode( // FUNCTION: LEGO1 0x1006aa60 // FUNCTION: BETA10 0x1004feee -void LegoAnimPresenter::FUN_1006aa60() +void LegoAnimPresenter::ReleaseManagedActors() { LegoROIListCursor cursor(m_managedActors); LegoROI* roi; @@ -540,16 +540,16 @@ void LegoAnimPresenter::FUN_1006aa60() while (cursor.Next(roi)) { const char* name = roi->GetName(); - if (m_unk0x96 || !CharacterManager()->IsActor(name)) { + if (m_localActors || !CharacterManager()->IsActor(name)) { CharacterManager()->ReleaseActor(name); } } } // FUNCTION: LEGO1 0x1006ab70 -void LegoAnimPresenter::FUN_1006ab70() +void LegoAnimPresenter::AppendManagedActors() { - if (m_unk0x96) { + if (m_localActors) { AnimationManager()->FUN_10063270(m_managedActors, this); } else { @@ -558,25 +558,25 @@ void LegoAnimPresenter::FUN_1006ab70() } // FUNCTION: LEGO1 0x1006aba0 -LegoBool LegoAnimPresenter::FUN_1006aba0() +LegoBool LegoAnimPresenter::VerifyAnimationTree() { - return FUN_1006abb0(m_anim->GetRoot(), 0); + return VerifyAnimationNode(m_anim->GetRoot(), NULL); } // FUNCTION: LEGO1 0x1006abb0 -MxBool LegoAnimPresenter::FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi) +MxBool LegoAnimPresenter::VerifyAnimationNode(LegoTreeNode* p_node, LegoROI* p_roi) { MxBool result = FALSE; LegoROI* roi = p_roi; - LegoChar* und = NULL; + LegoChar* varOrName = NULL; const LegoChar* name = ((LegoAnimNodeData*) p_node->GetData())->GetName(); MxS32 i, count; if (name != NULL && *name != '-') { - und = GetVariableOrIdentity(name, p_roi != NULL ? p_roi->GetName() : NULL); + varOrName = GetVariableOrIdentity(name, p_roi != NULL ? p_roi->GetName() : NULL); if (p_roi == NULL) { - roi = FindROI(und); + roi = FindROI(varOrName); if (roi == NULL) { goto done; @@ -587,7 +587,7 @@ MxBool LegoAnimPresenter::FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi) if (child == NULL) { if (FindROI(name) != NULL) { - if (FUN_1006abb0(p_node, NULL)) { + if (VerifyAnimationNode(p_node, NULL)) { result = TRUE; } } @@ -599,7 +599,7 @@ MxBool LegoAnimPresenter::FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi) count = p_node->GetNumChildren(); for (i = 0; i < count; i++) { - if (!FUN_1006abb0(p_node->GetChild(i), roi)) { + if (!VerifyAnimationNode(p_node->GetChild(i), roi)) { goto done; } } @@ -607,8 +607,8 @@ MxBool LegoAnimPresenter::FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi) result = TRUE; done: - if (und != NULL) { - delete[] und; + if (varOrName != NULL) { + delete[] varOrName; } return result; @@ -640,12 +640,12 @@ void LegoAnimPresenter::PutFrame() time = 0; } - FUN_1006b9a0(m_anim, time, m_unk0x78); + ApplyTransformWithVisibilityAndCam(m_anim, time, m_transform); - if (m_unk0x8c != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { - for (MxS32 i = 0; i < m_unk0x94; i++) { - if (m_unk0x8c[i] != NULL) { - MxMatrix mat(m_unk0x8c[i]->GetLocal2World()); + if (m_ptAtCamROI != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { + for (MxS32 i = 0; i < m_ptAtCamCount; i++) { + if (m_ptAtCamROI[i] != NULL) { + MxMatrix mat(m_ptAtCamROI[i]->GetLocal2World()); Vector3 pos(mat[0]); Vector3 dir(mat[1]); @@ -667,8 +667,8 @@ void LegoAnimPresenter::PutFrame() dir *= dirsqr; up *= upsqr; - m_unk0x8c[i]->SetLocal2World(mat); - m_unk0x8c[i]->WrappedUpdateWorldData(); + m_ptAtCamROI[i]->SetLocal2World(mat); + m_ptAtCamROI[i]->WrappedUpdateWorldData(); } } } @@ -677,7 +677,7 @@ void LegoAnimPresenter::PutFrame() // FUNCTION: LEGO1 0x1006afc0 // FUNCTION: BETA10 0x1005059a -MxResult LegoAnimPresenter::FUN_1006afc0(MxMatrix*& p_matrix, float p_und) +MxResult LegoAnimPresenter::GetTransforms(MxMatrix*& p_matrix, float p_time) { MxU32 length = m_roiMapSize + 1; p_matrix = new MxMatrix[length]; @@ -689,7 +689,7 @@ MxResult LegoAnimPresenter::FUN_1006afc0(MxMatrix*& p_matrix, float p_und) } } - FUN_1006b900(m_anim, p_und, m_unk0x78); + ApplyTransform(m_anim, p_time, m_transform); for (i = 1; i < length; i++) { MxMatrix mat; @@ -706,7 +706,7 @@ MxResult LegoAnimPresenter::FUN_1006afc0(MxMatrix*& p_matrix, float p_und) // FUNCTION: LEGO1 0x1006b140 // FUNCTION: BETA10 0x100507e0 -MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi) +MxResult LegoAnimPresenter::CopyTransform(LegoROI* p_roi) { if (p_roi == NULL) { return FAILURE; @@ -720,16 +720,16 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi) MxMatrix inverse; const Matrix4& local2world = p_roi->GetLocal2World(); - MxMatrix* local5c; + MxMatrix* roiTransforms; MxU32 i; - if (FUN_1006afc0(local5c, 0.0f) != SUCCESS) { + if (GetTransforms(roiTransforms, 0.0f) != SUCCESS) { goto done; } for (i = 1; i <= m_roiMapSize; i++) { if (m_roiMap[i] == p_roi) { - if (local5c[i].Invert(inverse) != SUCCESS) { + if (roiTransforms[i].Invert(inverse) != SUCCESS) { goto done; } @@ -739,15 +739,15 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi) { mn->Product(inverse, local2world); - SetUnknown0xa0(mn); - delete[] local5c; - SetUnknown0x0cTo1(); + SetRoiTransform(mn); + delete[] roiTransforms; + SetRoiTransformApplied(); - MxMatrix local140(*m_unk0x78); - MxMatrix localf8; + MxMatrix originalTransform(*m_transform); + MxMatrix newTransform; - localf8.Product(local140, *m_unk0xa0); - *m_unk0x78 = localf8; + newTransform.Product(originalTransform, *m_roiTransform); + *m_transform = newTransform; return SUCCESS; } @@ -756,8 +756,8 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi) delete mn; } - if (local5c != NULL) { - delete[] local5c; + if (roiTransforms != NULL) { + delete[] roiTransforms; } return FAILURE; @@ -793,22 +793,22 @@ void LegoAnimPresenter::ReadyTickle() void LegoAnimPresenter::StartingTickle() { SubstituteVariables(); - FUN_100692b0(); - FUN_100695c0(); + CreateManagedActors(); + CreateSceneROIs(); - if (m_flags & c_mustSucceed && !FUN_1006aba0()) { + if (m_flags & c_mustSucceed && !VerifyAnimationTree()) { goto done; } - FUN_10069b10(); + BuildROIMap(); SetDisabled(TRUE); - if (m_unk0x78 == NULL) { + if (m_transform == NULL) { if (fabs(m_action->GetDirection()[0]) >= 0.00000047683716F || fabs(m_action->GetDirection()[1]) >= 0.00000047683716F || fabs(m_action->GetDirection()[2]) >= 0.00000047683716F) { - m_unk0x78 = new MxMatrix(); - CalcLocalTransform(m_action->GetLocation(), m_action->GetDirection(), m_action->GetUp(), *m_unk0x78); + m_transform = new MxMatrix(); + CalcLocalTransform(m_action->GetLocation(), m_action->GetDirection(), m_action->GetUp(), *m_transform); } else if (m_roiMap != NULL) { LegoROI* roi = m_roiMap[1]; @@ -816,14 +816,14 @@ void LegoAnimPresenter::StartingTickle() if (roi != NULL) { MxMatrix mat; mat = roi->GetLocal2World(); - m_unk0x78 = new MxMatrix(mat); + m_transform = new MxMatrix(mat); } } } if ((m_action->GetDuration() == -1 || ((MxDSMediaAction*) m_action)->GetSustainTime() == -1) && m_compositePresenter) { - m_compositePresenter->VTable0x60(this); + m_compositePresenter->AdvanceSerialAction(this); } else { m_action->SetTimeStarted(Timer()->GetTime()); @@ -832,11 +832,11 @@ void LegoAnimPresenter::StartingTickle() ProgressTickleState(e_streaming); if (m_compositePresenter && m_compositePresenter->IsA("LegoAnimMMPresenter")) { - m_unk0x96 = ((LegoAnimMMPresenter*) m_compositePresenter)->FUN_1004b8b0(); - m_compositePresenter->VTable0x60(this); + m_localActors = ((LegoAnimMMPresenter*) m_compositePresenter)->FUN_1004b8b0(); + m_compositePresenter->AdvanceSerialAction(this); } - VTable0x8c(); + AddToWorld(); done: if (m_sceneROIs != NULL) { @@ -853,17 +853,17 @@ void LegoAnimPresenter::StreamingTickle() m_subscriber->FreeDataChunk(chunk); } - if (m_unk0x95) { + if (m_animationFinished) { ProgressTickleState(e_done); if (m_compositePresenter) { if (m_compositePresenter->IsA("LegoAnimMMPresenter")) { - m_compositePresenter->VTable0x60(this); + m_compositePresenter->AdvanceSerialAction(this); } } } else { if (m_action->GetElapsedTime() > m_anim->GetDuration() + m_action->GetStartTime()) { - m_unk0x95 = TRUE; + m_animationFinished = TRUE; } } } @@ -894,7 +894,7 @@ const char* LegoAnimPresenter::GetActionObjectName() // FUNCTION: LEGO1 0x1006b900 // FUNCTION: BETA10 0x100510d8 -void LegoAnimPresenter::FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix) +void LegoAnimPresenter::ApplyTransform(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix) { LegoTreeNode* root = p_anim->GetRoot(); MxMatrix mat; @@ -919,7 +919,7 @@ void LegoAnimPresenter::FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p // FUNCTION: LEGO1 0x1006b9a0 // FUNCTION: BETA10 0x1005118b -void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix) +void LegoAnimPresenter::ApplyTransformWithVisibilityAndCam(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix) { LegoTreeNode* root = p_anim->GetRoot(); MxMatrix mat; @@ -1010,43 +1010,43 @@ void LegoAnimPresenter::ParseExtra() } if (KeyValueStringParse(output, g_strPTATCAM, extraCopy)) { - list tmp; + list tokens; - if (m_unk0x90 != NULL) { - for (MxS32 i = 0; i < m_unk0x94; i++) { - if (m_unk0x90[i] != NULL) { + if (m_ptAtCamNames != NULL) { + for (MxS32 i = 0; i < m_ptAtCamCount; i++) { + if (m_ptAtCamNames[i] != NULL) { // (modernization) critical bug: wrong free - delete[] m_unk0x90; + delete[] m_ptAtCamNames; } } - delete[] m_unk0x90; - m_unk0x90 = NULL; + delete[] m_ptAtCamNames; + m_ptAtCamNames = NULL; } - if (m_unk0x8c != NULL) { - delete[] m_unk0x8c; - m_unk0x8c = NULL; + if (m_ptAtCamROI != NULL) { + delete[] m_ptAtCamROI; + m_ptAtCamROI = NULL; } char* token = strtok(output, g_parseExtraTokens); while (token != NULL) { char* valueCopy = new char[strlen(token) + 1]; strcpy(valueCopy, token); - tmp.push_back(valueCopy); + tokens.push_back(valueCopy); token = strtok(NULL, g_parseExtraTokens); } - m_unk0x94 = tmp.size(); - if (m_unk0x94 != 0) { - m_unk0x8c = new LegoROI*[m_unk0x94]; - m_unk0x90 = new char*[m_unk0x94]; - memset(m_unk0x8c, 0, sizeof(*m_unk0x8c) * m_unk0x94); - memset(m_unk0x90, 0, sizeof(*m_unk0x90) * m_unk0x94); + m_ptAtCamCount = tokens.size(); + if (m_ptAtCamCount != 0) { + m_ptAtCamROI = new LegoROI*[m_ptAtCamCount]; + m_ptAtCamNames = new char*[m_ptAtCamCount]; + memset(m_ptAtCamROI, 0, sizeof(*m_ptAtCamROI) * m_ptAtCamCount); + memset(m_ptAtCamNames, 0, sizeof(*m_ptAtCamNames) * m_ptAtCamCount); MxS32 i = 0; - for (list::iterator it = tmp.begin(); it != tmp.end(); it++, i++) { - m_unk0x90[i] = *it; + for (list::iterator it = tokens.begin(); it != tokens.end(); it++, i++) { + m_ptAtCamNames[i] = *it; } } } @@ -1055,13 +1055,13 @@ void LegoAnimPresenter::ParseExtra() // FUNCTION: LEGO1 0x1006c570 // FUNCTION: BETA10 0x10051ab3 -void LegoAnimPresenter::VTable0xa0(Matrix4& p_matrix) +void LegoAnimPresenter::SetTransform(Matrix4& p_matrix) { - if (m_unk0x78 != NULL) { - delete m_unk0x78; + if (m_transform != NULL) { + delete m_transform; } - m_unk0x78 = new MxMatrix(p_matrix); + m_transform = new MxMatrix(p_matrix); } // FUNCTION: LEGO1 0x1006c620 @@ -1090,7 +1090,7 @@ void LegoAnimPresenter::EndAction() } if (m_anim != NULL) { - FUN_1006b9a0(m_anim, m_anim->GetDuration(), m_unk0x78); + ApplyTransformWithVisibilityAndCam(m_anim, m_anim->GetDuration(), m_transform); } if (m_roiMapSize != 0 && m_roiMap != NULL && m_roiMap[1] != NULL && m_flags & c_hideOnStop) { @@ -1102,8 +1102,8 @@ void LegoAnimPresenter::EndAction() } SetDisabled(FALSE); - FUN_1006ab70(); - VTable0x90(); + AppendManagedActors(); + RemoveFromWorld(); if (m_currentWorld != NULL) { m_currentWorld->Remove(this); @@ -1114,24 +1114,24 @@ void LegoAnimPresenter::EndAction() // FUNCTION: LEGO1 0x1006c7a0 // FUNCTION: BETA10 0x10051da6 -void LegoAnimPresenter::FUN_1006c7a0() +void LegoAnimPresenter::ApplyFinishedTransform() { if (m_anim != NULL) { - FUN_1006b9a0(m_anim, m_anim->GetDuration(), m_unk0x78); + ApplyTransformWithVisibilityAndCam(m_anim, m_anim->GetDuration(), m_transform); } - m_unk0x95 = TRUE; + m_animationFinished = TRUE; } // FUNCTION: LEGO1 0x1006c7d0 // FUNCTION: BETA10 0x10051e07 -void LegoAnimPresenter::VTable0x8c() +void LegoAnimPresenter::AddToWorld() { - if (m_unk0x78) { - m_unk0xa8 += (*m_unk0x78)[3]; + if (m_transform) { + m_centerPoint += (*m_transform)[3]; } else { - m_unk0xa8 += m_action->GetLocation(); + m_centerPoint += m_action->GetLocation(); } if (m_currentWorld == NULL) { @@ -1148,7 +1148,7 @@ void LegoAnimPresenter::VTable0x8c() // FUNCTION: LEGO1 0x1006c860 // FUNCTION: BETA10 0x10051f45 -void LegoAnimPresenter::VTable0x90() +void LegoAnimPresenter::RemoveFromWorld() { if (m_currentWorld != NULL) { m_currentWorld->RemovePresenterFromBoundaries(this); @@ -1182,26 +1182,34 @@ void LegoAnimPresenter::SetDisabled(MxBool p_disabled) // FUNCTION: LEGO1 0x1006c8f0 // FUNCTION: BETA10 0x1005206c -MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3) +MxU32 LegoAnimPresenter::Intersect( + Vector3& p_rayOrigin, + Vector3& p_rayDirection, + float p_rayLength, + float p_radius, + Vector3& p_intersectionPoint +) { - Mx3DPointFloat a, b; + Mx3DPointFloat centerToRay, rayEnd; - b = p_v2; - b *= p_f1; - b += p_v1; + rayEnd = p_rayDirection; + rayEnd *= p_rayLength; + rayEnd += p_rayOrigin; - a = b; - a -= m_unk0xa8; + centerToRay = rayEnd; + centerToRay -= m_centerPoint; - float len = a.LenSquared(); + float len = centerToRay.LenSquared(); if (len <= 0.0f) { return TRUE; } len = sqrt(len); - if (len <= m_unk0xa4 + p_f2 && m_roiMapSize != 0 && m_roiMap != NULL) { + if (len <= m_boundingRadius + p_radius && m_roiMapSize != 0 && m_roiMap != NULL) { for (MxU32 i = 1; i <= m_roiMapSize; i++) { - if (m_roiMap[i]->GetLODCount() != 0 && m_roiMap[i]->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, FALSE)) { + if (m_roiMap[i]->GetLODCount() != 0 && + m_roiMap[i] + ->Intersect(p_rayOrigin, p_rayDirection, p_rayLength, p_radius, p_intersectionPoint, FALSE)) { return TRUE; } } @@ -1212,7 +1220,7 @@ MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, fl // FUNCTION: LEGO1 0x1006ca50 // FUNCTION: BETA10 0x100521d0 -MxResult LegoAnimPresenter::VTable0x98(LegoPathBoundary* p_boundary) +MxResult LegoAnimPresenter::AddActors(LegoPathBoundary* p_boundary) { for (MxU32 i = 1; i <= m_roiMapSize; i++) { LegoEntity* entity = m_roiMap[i]->GetEntity(); @@ -1234,18 +1242,18 @@ void LegoLoopingAnimPresenter::StreamingTickle() m_subscriber->FreeDataChunk(chunk); } - if (m_unk0x95) { + if (m_animationFinished) { ProgressTickleState(e_done); if (m_compositePresenter) { if (m_compositePresenter->IsA("LegoAnimMMPresenter")) { - m_compositePresenter->VTable0x60(this); + m_compositePresenter->AdvanceSerialAction(this); } } } else { if (m_action->GetDuration() != -1) { if (m_action->GetElapsedTime() > m_action->GetDuration() + m_action->GetStartTime()) { - m_unk0x95 = TRUE; + m_animationFinished = TRUE; } } } @@ -1264,12 +1272,12 @@ void LegoLoopingAnimPresenter::PutFrame() time = 0; } - FUN_1006b9a0(m_anim, time, m_unk0x78); + ApplyTransformWithVisibilityAndCam(m_anim, time, m_transform); - if (m_unk0x8c != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { - for (MxS32 i = 0; i < m_unk0x94; i++) { - if (m_unk0x8c[i] != NULL) { - MxMatrix mat(m_unk0x8c[i]->GetLocal2World()); + if (m_ptAtCamROI != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { + for (MxS32 i = 0; i < m_ptAtCamCount; i++) { + if (m_ptAtCamROI[i] != NULL) { + MxMatrix mat(m_ptAtCamROI[i]->GetLocal2World()); Vector3 pos(mat[0]); Vector3 dir(mat[1]); @@ -1291,8 +1299,8 @@ void LegoLoopingAnimPresenter::PutFrame() dir *= dirsqr; up *= upsqr; - m_unk0x8c[i]->SetLocal2World(mat); - m_unk0x8c[i]->WrappedUpdateWorldData(); + m_ptAtCamROI[i]->SetLocal2World(mat); + m_ptAtCamROI[i]->WrappedUpdateWorldData(); } } } @@ -1318,7 +1326,7 @@ void LegoLocomotionAnimPresenter::Init() m_unk0xcc = -1; m_unk0xd0 = -1; m_roiMapList = NULL; - m_unk0xd4 = 0; + m_worldRefCounter = 0; } // FUNCTION: LEGO1 0x1006d0e0 @@ -1387,7 +1395,7 @@ void LegoLocomotionAnimPresenter::ReadyTickle() SendToCompositePresenter(Lego()); } - m_unk0xd4++; + m_worldRefCounter++; } } @@ -1408,7 +1416,7 @@ void LegoLocomotionAnimPresenter::StartingTickle() // FUNCTION: LEGO1 0x1006d660 void LegoLocomotionAnimPresenter::StreamingTickle() { - if (m_unk0xd4 == 0) { + if (m_worldRefCounter == 0) { EndAction(); } } @@ -1423,7 +1431,7 @@ void LegoLocomotionAnimPresenter::EndAction() // FUNCTION: LEGO1 0x1006d680 // FUNCTION: BETA10 0x10052b3d -void LegoLocomotionAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value) +void LegoLocomotionAnimPresenter::CreateROIAndBuildMap(LegoAnimActor* p_actor, MxFloat p_worldSpeed) { // This asserts that LegoLocomotionAnimPresenter is contained in legoanimpresenter.cpp AUTOLOCK(m_criticalSection); @@ -1433,12 +1441,12 @@ void LegoLocomotionAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p const char* key = ((LegoAnimNodeData*) m_anim->GetRoot()->GetData())->GetName(); variableTable->SetVariable(key, p_actor->GetROI()->GetName()); - FUN_100695c0(); - FUN_10069b10(); + CreateSceneROIs(); + BuildROIMap(); if (m_roiMap != NULL) { m_roiMapList->Append(m_roiMap); - p_actor->CreateAnimActorStruct(m_anim, p_value, m_roiMap, m_roiMapSize); + p_actor->CreateAnimActorStruct(m_anim, p_worldSpeed, m_roiMap, m_roiMapSize); m_roiMap = NULL; } @@ -1529,21 +1537,21 @@ void LegoHideAnimPresenter::StartingTickle() LegoLoopingAnimPresenter::StartingTickle(); if (m_currentTickleState == e_streaming) { - FUN_1006dc10(); - FUN_1006db40(0); + AssignIndiciesWithMap(); + ApplyVisibility(0); } } // FUNCTION: LEGO1 0x1006db40 // FUNCTION: BETA10 0x100531ab -void LegoHideAnimPresenter::FUN_1006db40(LegoTime p_time) +void LegoHideAnimPresenter::ApplyVisibility(LegoTime p_time) { - FUN_1006db60(m_anim->GetRoot(), p_time); + ApplyVisibility(m_anim->GetRoot(), p_time); } // FUNCTION: LEGO1 0x1006db60 // FUNCTION: BETA10 0x100531de -void LegoHideAnimPresenter::FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time) +void LegoHideAnimPresenter::ApplyVisibility(LegoTreeNode* p_node, LegoTime p_time) { LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData(); MxBool newB = FALSE; @@ -1564,23 +1572,23 @@ void LegoHideAnimPresenter::FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time) if (boundary != NULL) { newB = data->GetVisibility(p_time); - previousB = boundary->GetFlag0x10(); - boundary->SetFlag0x10(newB); + previousB = boundary->GetVisibility(); + boundary->SetVisibility(newB); } } for (MxS32 i = 0; i < p_node->GetNumChildren(); i++) { - FUN_1006db60(p_node->GetChild(i), p_time); + ApplyVisibility(p_node->GetChild(i), p_time); } } // FUNCTION: LEGO1 0x1006dc10 // FUNCTION: BETA10 0x100532fd -void LegoHideAnimPresenter::FUN_1006dc10() +void LegoHideAnimPresenter::AssignIndiciesWithMap() { LegoHideAnimStructMap anims; - FUN_1006e3f0(anims, m_anim->GetRoot()); + BuildMap(anims, m_anim->GetRoot()); if (m_boundaryMap != NULL) { delete[] m_boundaryMap; @@ -1597,7 +1605,7 @@ void LegoHideAnimPresenter::FUN_1006dc10() // FUNCTION: LEGO1 0x1006e3f0 // FUNCTION: BETA10 0x1005345e -void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node) +void LegoHideAnimPresenter::BuildMap(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node) { LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData(); const char* name = data->GetName(); @@ -1606,7 +1614,7 @@ void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeN LegoPathBoundary* boundary = m_currentWorld->FindPathBoundary(name); if (boundary != NULL) { - FUN_1006e470(p_map, data, name, boundary); + CheckedAdd(p_map, data, name, boundary); } else { data->SetBoundaryIndex(0); @@ -1615,13 +1623,13 @@ void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeN MxS32 count = p_node->GetNumChildren(); for (MxS32 i = 0; i < count; i++) { - FUN_1006e3f0(p_map, p_node->GetChild(i)); + BuildMap(p_map, p_node->GetChild(i)); } } // FUNCTION: LEGO1 0x1006e470 // FUNCTION: BETA10 0x10053520 -void LegoHideAnimPresenter::FUN_1006e470( +void LegoHideAnimPresenter::CheckedAdd( LegoHideAnimStructMap& p_map, LegoAnimNodeData* p_data, const char* p_name, diff --git a/LEGO1/lego/legoomni/src/video/legotexturepresenter.cpp b/LEGO1/lego/legoomni/src/video/legotexturepresenter.cpp index 305692f4..02e87f89 100644 --- a/LEGO1/lego/legoomni/src/video/legotexturepresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legotexturepresenter.cpp @@ -141,7 +141,7 @@ MxResult LegoTexturePresenter::PutData() // FUNCTION: LEGO1 0x1004fcb0 void LegoTexturePresenter::DoneTickle() { - if (this->m_compositePresenter && !this->m_compositePresenter->VTable0x64(2)) { + if (this->m_compositePresenter && !this->m_compositePresenter->GetActionEnded(2)) { SetTickleState(e_idle); return; } diff --git a/LEGO1/lego/legoomni/src/worlds/act3.cpp b/LEGO1/lego/legoomni/src/worlds/act3.cpp index f897bc2e..e8fc3df6 100644 --- a/LEGO1/lego/legoomni/src/worlds/act3.cpp +++ b/LEGO1/lego/legoomni/src/worlds/act3.cpp @@ -331,15 +331,15 @@ MxResult Act3::ShootPizza(LegoPathController* p_controller, Vector3& p_location, m_pizzas[nextPizza].Create(this, TRUE, nextPizza); - if (m_pizzas[nextPizza].FUN_10053b40(p_location, p_direction, p_up) != SUCCESS) { + if (m_pizzas[nextPizza].CalculateArc(p_location, p_direction, p_up) != SUCCESS) { return FAILURE; } - MxFloat unk0x19c = *m_pizzas[nextPizza].GetUnknown0x19c(); - if (p_controller->FUN_1004a380( + MxFloat unk0x19c = *m_pizzas[nextPizza].GetApexParameter(); + if (p_controller->FindIntersectionBoundary( p_location, p_direction, - m_pizzas[nextPizza].GetUnknown0x160(), + m_pizzas[nextPizza].GetCoefficients(), boundary, unk0x19c ) == SUCCESS) { @@ -354,7 +354,7 @@ MxResult Act3::ShootPizza(LegoPathController* p_controller, Vector3& p_location, direction -= m_brickster->GetROI()->GetLocal2World()[3]; local18 = FALSE; - if (m_pizzas[nextPizza].FUN_10053cb0(p_controller, boundary, unk0x19c) == SUCCESS) { + if (m_pizzas[nextPizza].Shoot(p_controller, boundary, unk0x19c) == SUCCESS) { p_controller->PlaceActor(&m_pizzas[nextPizza]); boundary->AddActor(&m_pizzas[nextPizza]); m_pizzas[nextPizza].SetWorldSpeed(10.0f); @@ -362,7 +362,7 @@ MxResult Act3::ShootPizza(LegoPathController* p_controller, Vector3& p_location, } } - if (local18 && m_pizzas[nextPizza].FUN_10053d30(p_controller, unk0x19c) == SUCCESS) { + if (local18 && m_pizzas[nextPizza].Shoot(p_controller, unk0x19c) == SUCCESS) { p_controller->PlaceActor(&m_pizzas[nextPizza]); m_pizzas[nextPizza].SetWorldSpeed(10.0f); return SUCCESS; @@ -386,26 +386,26 @@ MxResult Act3::ShootDonut(LegoPathController* p_controller, Vector3& p_location, m_donuts[nextDonut].Create(this, FALSE, nextDonut); - if (m_donuts[nextDonut].FUN_10053b40(p_location, p_direction, p_up) != SUCCESS) { + if (m_donuts[nextDonut].CalculateArc(p_location, p_direction, p_up) != SUCCESS) { return FAILURE; } - MxFloat unk0x19c = *m_donuts[nextDonut].GetUnknown0x19c(); - if (p_controller->FUN_1004a380( + MxFloat unk0x19c = *m_donuts[nextDonut].GetApexParameter(); + if (p_controller->FindIntersectionBoundary( p_location, p_direction, - m_donuts[nextDonut].GetUnknown0x160(), + m_donuts[nextDonut].GetCoefficients(), boundary, unk0x19c ) == SUCCESS) { - if (m_donuts[nextDonut].FUN_10053cb0(p_controller, boundary, unk0x19c) == SUCCESS) { + if (m_donuts[nextDonut].Shoot(p_controller, boundary, unk0x19c) == SUCCESS) { p_controller->PlaceActor(&m_donuts[nextDonut]); boundary->AddActor(&m_donuts[nextDonut]); m_donuts[nextDonut].SetWorldSpeed(10.0f); return SUCCESS; } } - else if (m_donuts[nextDonut].FUN_10053d30(p_controller, unk0x19c) == SUCCESS) { + else if (m_donuts[nextDonut].Shoot(p_controller, unk0x19c) == SUCCESS) { p_controller->PlaceActor(&m_donuts[nextDonut]); m_donuts[nextDonut].SetWorldSpeed(10.0f); return SUCCESS; @@ -583,13 +583,13 @@ MxLong Act3::Notify(MxParam& p_param) m_cop1->SetActorState(LegoPathActor::c_initial); m_cop1->SetWorldSpeed(2.0f); - m_cop1->VTable0xa8(); + m_cop1->ApplyLocal2World(); m_cop2->SetActorState(LegoPathActor::c_initial); m_cop2->SetWorldSpeed(2.0f); - m_cop2->VTable0xa8(); + m_cop2->ApplyLocal2World(); - m_brickster->VTable0xa8(); + m_brickster->ApplyLocal2World(); m_pizzaHitSound = 0; m_pizzaMissSound = 0; m_copDonutSound = 0; @@ -912,44 +912,44 @@ void Act3::Enable(MxBool p_enable) MxFloat delta = Timer()->GetTime() - m_time - 100.0f; m_time = -1.0f; - m_cop1->SetLastTime(m_cop1->GetLastTime() + delta); + m_cop1->SetTransformTime(m_cop1->GetTransformTime() + delta); m_cop1->SetActorTime(m_cop1->GetActorTime() + delta); m_cop1->SetUnknown0x20(m_cop1->GetUnknown0x20() + delta); m_cop1->SetUnknown0x1c(m_cop1->GetUnknown0x1c() + delta); - m_cop2->SetLastTime(m_cop2->GetLastTime() + delta); + m_cop2->SetTransformTime(m_cop2->GetTransformTime() + delta); m_cop2->SetActorTime(m_cop2->GetActorTime() + delta); m_cop2->SetUnknown0x20(m_cop2->GetUnknown0x20() + delta); m_cop2->SetUnknown0x1c(m_cop2->GetUnknown0x1c() + delta); - m_brickster->SetLastTime(m_brickster->GetLastTime() + delta); + m_brickster->SetTransformTime(m_brickster->GetTransformTime() + delta); m_brickster->SetActorTime(m_brickster->GetActorTime() + delta); m_brickster->SetUnknown0x20(m_brickster->GetUnknown0x20() + delta); m_brickster->SetUnknown0x24(m_brickster->GetUnknown0x24() + delta); m_brickster->SetUnknown0x50(m_brickster->GetUnknown0x50() + delta); m_brickster->SetUnknown0x1c(m_brickster->GetUnknown0x1c() + delta); - m_copter->SetLastTime(m_copter->GetLastTime() + delta); + m_copter->SetTransformTime(m_copter->GetTransformTime() + delta); m_copter->SetActorTime(m_copter->GetActorTime() + delta); - m_shark->SetLastTime(m_shark->GetLastTime() + delta); + m_shark->SetTransformTime(m_shark->GetTransformTime() + delta); m_shark->SetActorTime(m_shark->GetActorTime() + delta); m_shark->SetUnknown0x2c(m_shark->GetUnknown0x2c() + delta); MxS32 i; for (i = 0; i < (MxS32) sizeOfArray(m_pizzas); i++) { if (m_pizzas[i].IsValid()) { - m_pizzas[i].SetLastTime(m_pizzas[i].GetLastTime() + delta); + m_pizzas[i].SetTransformTime(m_pizzas[i].GetTransformTime() + delta); m_pizzas[i].SetActorTime(m_pizzas[i].GetActorTime() + delta); - m_pizzas[i].SetUnknown0x158(m_pizzas[i].GetUnknown0x158() + delta); + m_pizzas[i].SetRotateTimeout(m_pizzas[i].GetRotateTimeout() + delta); } } for (i = 0; i < (MxS32) sizeOfArray(m_donuts); i++) { if (m_donuts[i].IsValid()) { - m_donuts[i].SetLastTime(m_donuts[i].GetLastTime() + delta); + m_donuts[i].SetTransformTime(m_donuts[i].GetTransformTime() + delta); m_donuts[i].SetActorTime(m_donuts[i].GetActorTime() + delta); - m_donuts[i].SetUnknown0x158(m_donuts[i].GetUnknown0x158() + delta); + m_donuts[i].SetRotateTimeout(m_donuts[i].GetRotateTimeout() + delta); } } @@ -959,7 +959,7 @@ void Act3::Enable(MxBool p_enable) InputManager()->SetWorld(this); InputManager()->Register(this); SetUserActor(m_copter); - m_copter->VTable0xa8(); + m_copter->ApplyLocal2World(); SetAppCursor(e_cursorArrow); } } diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index b06a0a61..d1908fe3 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -878,7 +878,7 @@ void Isle::CheckAreaExiting() case LegoGameState::e_vehicleExited: { MxMatrix mat(UserActor()->GetROI()->GetLocal2World()); LegoPathBoundary* boundary = UserActor()->GetBoundary(); - ((IslePathActor*) UserActor())->VTable0xec(mat, boundary, TRUE); + ((IslePathActor*) UserActor())->UpdateWorld(mat, boundary, TRUE); break; } case LegoGameState::e_infocenterExited: diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 85faa9e1..1d969314 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -534,7 +534,7 @@ void LegoAct2::Enable(MxBool p_enable) GameState()->SetActor(LegoActor::c_pepper); m_pepper = FindROI("pepper"); - ((IslePathActor*) m_pepper->GetEntity())->VTable0xec(m_transformOnDisable, m_boundaryOnDisable, TRUE); + ((IslePathActor*) m_pepper->GetEntity())->UpdateWorld(m_transformOnDisable, m_boundaryOnDisable, TRUE); if (GameState()->m_previousArea == LegoGameState::e_infomain) { GameState()->StopArea(LegoGameState::e_infomain); @@ -1209,19 +1209,19 @@ MxResult LegoAct2::InitializeShooting() ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim0"); assert(ap); - ap->FUN_1006d680(m_unk0x1138, 0.0f); + ap->CreateROIAndBuildMap(m_unk0x1138, 0.0f); ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim2"); assert(ap); - ap->FUN_1006d680(m_unk0x1138, 6.0f); + ap->CreateROIAndBuildMap(m_unk0x1138, 6.0f); ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim3"); assert(ap); - ap->FUN_1006d680(m_unk0x1138, 3.0f); + ap->CreateROIAndBuildMap(m_unk0x1138, 3.0f); ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "BrShoot"); assert(ap); - ap->FUN_1006d680(m_unk0x1138, -1.0f); + ap->CreateROIAndBuildMap(m_unk0x1138, -1.0f); actor->SetWorldSpeed(0.0f); m_unk0x1138->InitializeNextShot(); diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index 1c297c4d..3b935f85 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -290,11 +290,11 @@ class LegoAnimNodeData : public LegoTreeNodeData { // SIZE 0x08 struct LegoAnimActorEntry { enum { - e_actorType2 = 2, - e_actorType3 = 3, - e_actorType4 = 4, - e_actorType5 = 5, - e_actorType6 = 6, + e_managedLegoActor = 2, + e_managedInvisibleRoiTrimmed = 3, + e_managedInvisibleRoi = 4, + e_sceneRoi1 = 5, + e_sceneRoi2 = 6, }; LegoChar* m_name; // 0x00 diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index ea9fab08..fa9da58a 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -37,7 +37,7 @@ class LegoWEGEdge : public LegoWEEdge { c_bit1 = 0x01, c_bit2 = 0x02, c_bit3 = 0x04, - c_bit5 = 0x10 + c_visible = 0x10 }; LegoWEGEdge(); @@ -46,9 +46,9 @@ class LegoWEGEdge : public LegoWEEdge { LegoS32 LinkEdgesAndFaces() override; // vtable+0x04 // FUNCTION: BETA10 0x100270c0 - LegoU32 GetFlag0x10() + LegoU32 GetVisibility() { - if (m_flags & c_bit5) { + if (m_flags & c_visible) { return FALSE; } else { @@ -67,13 +67,13 @@ class LegoWEGEdge : public LegoWEEdge { const LegoChar* GetName() { return m_name; } // FUNCTION: BETA10 0x1005d5f0 - void SetFlag0x10(LegoU32 p_disable) + void SetVisibility(LegoU32 p_disable) { if (p_disable) { - m_flags &= ~c_bit5; + m_flags &= ~c_visible; } else { - m_flags |= c_bit5; + m_flags |= c_visible; } } diff --git a/LEGO1/lego/sources/misc/legospline.cpp b/LEGO1/lego/sources/misc/legospline.cpp new file mode 100644 index 00000000..b5d0a217 --- /dev/null +++ b/LEGO1/lego/sources/misc/legospline.cpp @@ -0,0 +1,88 @@ +#include "legospline.h" + +#include "mxgeometry/mxmatrix.h" + +DECOMP_SIZE_ASSERT(LegoSpline, 0x50) + +// FUNCTION: LEGO1 0x1009a0f0 +LegoSpline::LegoSpline() +{ + for (LegoS32 i = 0; i < sizeOfArray(m_coefficents); i++) { + m_coefficents[i].Clear(); + } +} + +// FUNCTION: LEGO1 0x1009a130 +LegoSpline::~LegoSpline() +{ +} + +// FUNCTION: LEGO1 0x1009a140 +// FUNCTION: BETA10 0x10182c2f +void LegoSpline::SetSpline( + const Vector3& p_start, + const Vector3& p_tangentAtStart, + const Vector3& p_end, + const Vector3& p_tangentAtEnd +) +{ + m_coefficents[0] = p_start; + m_coefficents[1] = p_tangentAtStart; + + for (LegoS32 i = 0; i < 3; i++) { + m_coefficents[2][i] = (p_end[i] - p_start[i]) * 3.0f - p_tangentAtStart[i] * 2.0f - p_tangentAtEnd[i]; + m_coefficents[3][i] = (p_start[i] - p_end[i]) * 2.0f + p_tangentAtEnd[i] + p_tangentAtStart[i]; + } +} + +// FUNCTION: LEGO1 0x1009a1e0 +// FUNCTION: BETA10 0x10182d61 +LegoResult LegoSpline::Evaluate(float p_alpha, Matrix4& p_mat, Vector3& p_up, LegoU32 p_reverse) +{ + Vector3 position(p_mat[3]); + Vector3 right(p_mat[0]); + Vector3 up(p_mat[1]); + Vector3 dir(p_mat[2]); + + if (isnan(p_alpha) || p_alpha <= 0.001) { + position = m_coefficents[0]; + dir = m_coefficents[1]; + } + else if (p_alpha >= 0.999) { + position = m_coefficents[0]; + position += m_coefficents[1]; + position += m_coefficents[2]; + position += m_coefficents[3]; + + for (LegoS32 i = 0; i < 3; i++) { + dir[i] = m_coefficents[1][i] + m_coefficents[2][i] * 2.0f + m_coefficents[3][i] * 3.0f; + } + } + else { + float alpha_squared = p_alpha * p_alpha; + float alpha_cubed = alpha_squared * p_alpha; + + for (LegoS32 i = 0; i < 3; i++) { + position[i] = m_coefficents[0][i] + m_coefficents[1][i] * p_alpha + m_coefficents[2][i] * alpha_squared + + m_coefficents[3][i] * alpha_cubed; + dir[i] = + m_coefficents[1][i] + m_coefficents[2][i] * p_alpha * 2.0f + m_coefficents[3][i] * alpha_squared * 3.0f; + } + } + + if (p_reverse) { + dir *= -1.0f; + } + + if (dir.Unitize() != 0) { + return FAILURE; + } + + right.EqualsCross(p_up, dir); + if (right.Unitize() != 0) { + return FAILURE; + } + + up.EqualsCross(dir, right); + return SUCCESS; +} diff --git a/LEGO1/lego/sources/misc/legospline.h b/LEGO1/lego/sources/misc/legospline.h new file mode 100644 index 00000000..b504dd7c --- /dev/null +++ b/LEGO1/lego/sources/misc/legospline.h @@ -0,0 +1,27 @@ +#ifndef __LEGOSPLINE_H +#define __LEGOSPLINE_H + +#include "legotypes.h" +#include "mxgeometry/mxgeometry3d.h" + +class Matrix4; + +// SIZE 0x50 +class LegoSpline { +public: + LegoSpline(); + ~LegoSpline(); + + void SetSpline( + const Vector3& p_start, + const Vector3& p_tangentAtStart, + const Vector3& p_end, + const Vector3& p_tangentAtEnd + ); + LegoResult Evaluate(float p_alpha, Matrix4& p_mat, Vector3& p_v, LegoU32 p_reverse); + +private: + Mx3DPointFloat m_coefficents[4]; // 0x00 +}; + +#endif // __LEGOSPLINE_H diff --git a/LEGO1/lego/sources/misc/legounknown.cpp b/LEGO1/lego/sources/misc/legounknown.cpp deleted file mode 100644 index bd7d77b7..00000000 --- a/LEGO1/lego/sources/misc/legounknown.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "legounknown.h" - -#include "mxgeometry/mxmatrix.h" - -DECOMP_SIZE_ASSERT(LegoUnknown, 0x50) - -// FUNCTION: LEGO1 0x1009a0f0 -LegoUnknown::LegoUnknown() -{ - for (LegoS32 i = 0; i < sizeOfArray(m_unk0x00); i++) { - m_unk0x00[i].Clear(); - } -} - -// FUNCTION: LEGO1 0x1009a130 -LegoUnknown::~LegoUnknown() -{ -} - -// FUNCTION: LEGO1 0x1009a140 -// FUNCTION: BETA10 0x10182c2f -void LegoUnknown::FUN_1009a140( - const Vector3& p_point1, - const Vector3& p_point2, - const Vector3& p_point3, - const Vector3& p_point4 -) -{ - m_unk0x00[0] = p_point1; - m_unk0x00[1] = p_point2; - - for (LegoS32 i = 0; i < 3; i++) { - m_unk0x00[2][i] = (p_point3[i] - p_point1[i]) * 3.0f - p_point2[i] * 2.0f - p_point4[i]; - m_unk0x00[3][i] = (p_point1[i] - p_point3[i]) * 2.0f + p_point4[i] + p_point2[i]; - } -} - -// FUNCTION: LEGO1 0x1009a1e0 -// FUNCTION: BETA10 0x10182d61 -LegoResult LegoUnknown::FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, LegoU32 p_und) -{ - Vector3 v1(p_mat[3]); - Vector3 v2(p_mat[0]); - Vector3 v3(p_mat[1]); - Vector3 v4(p_mat[2]); - - if (isnan(p_f1) || p_f1 <= 0.001) { - v1 = m_unk0x00[0]; - v4 = m_unk0x00[1]; - } - else if (p_f1 >= 0.999) { - v1 = m_unk0x00[0]; - v1 += m_unk0x00[1]; - v1 += m_unk0x00[2]; - v1 += m_unk0x00[3]; - - for (LegoS32 i = 0; i < 3; i++) { - v4[i] = m_unk0x00[1][i] + m_unk0x00[2][i] * 2.0f + m_unk0x00[3][i] * 3.0f; - } - } - else { - float local30 = p_f1 * p_f1; - float local34 = local30 * p_f1; - - for (LegoS32 i = 0; i < 3; i++) { - v1[i] = m_unk0x00[0][i] + m_unk0x00[1][i] * p_f1 + m_unk0x00[2][i] * local30 + m_unk0x00[3][i] * local34; - v4[i] = m_unk0x00[1][i] + m_unk0x00[2][i] * p_f1 * 2.0f + m_unk0x00[3][i] * local30 * 3.0f; - } - } - - if (p_und) { - v4 *= -1.0f; - } - - if (v4.Unitize() != 0) { - return FAILURE; - } - - v2.EqualsCross(p_v, v4); - if (v2.Unitize() != 0) { - return FAILURE; - } - - v3.EqualsCross(v4, v2); - return SUCCESS; -} diff --git a/LEGO1/lego/sources/misc/legounknown.h b/LEGO1/lego/sources/misc/legounknown.h deleted file mode 100644 index c29bbd28..00000000 --- a/LEGO1/lego/sources/misc/legounknown.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __LEGOUNKNOWN_H -#define __LEGOUNKNOWN_H - -#include "legotypes.h" -#include "mxgeometry/mxgeometry3d.h" - -class Matrix4; - -// SIZE 0x50 -class LegoUnknown { -public: - LegoUnknown(); - ~LegoUnknown(); - - void FUN_1009a140( - const Vector3& p_point1, - const Vector3& p_point2, - const Vector3& p_point3, - const Vector3& p_point4 - ); - LegoResult FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, LegoU32 p_und); - -private: - Mx3DPointFloat m_unk0x00[4]; // 0x00 -}; - -#endif // __LEGOUNKNOWN_H diff --git a/LEGO1/lego1_pch.h b/LEGO1/lego1_pch.h index 0797d498..a8cb49c8 100644 --- a/LEGO1/lego1_pch.h +++ b/LEGO1/lego1_pch.h @@ -163,11 +163,11 @@ #include "lego/sources/geom/legowegedge.h" #include "lego/sources/misc/legocontainer.h" #include "lego/sources/misc/legoimage.h" +#include "lego/sources/misc/legospline.h" #include "lego/sources/misc/legostorage.h" #include "lego/sources/misc/legotexture.h" #include "lego/sources/misc/legotree.h" #include "lego/sources/misc/legotypes.h" -#include "lego/sources/misc/legounknown.h" #include "lego/sources/misc/legoutil.h" #include "lego/sources/misc/version.h" #include "lego/sources/roi/legolod.h" diff --git a/LEGO1/omni/include/mxcompositepresenter.h b/LEGO1/omni/include/mxcompositepresenter.h index c11410dc..1f921ca4 100644 --- a/LEGO1/omni/include/mxcompositepresenter.h +++ b/LEGO1/omni/include/mxcompositepresenter.h @@ -43,15 +43,15 @@ class MxCompositePresenter : public MxPresenter { void SetTickleState(TickleState p_tickleState) override; // vtable+0x44 MxBool HasTickleStatePassed(TickleState p_tickleState) override; // vtable+0x48 void Enable(MxBool p_enable) override; // vtable+0x54 - virtual void VTable0x58(MxEndActionNotificationParam& p_param); // vtable+0x58 - virtual void VTable0x5c(MxNotificationParam& p_param); // vtable+0x5c - virtual void VTable0x60(MxPresenter* p_presenter); // vtable+0x60 + virtual void HandleEndAction(MxEndActionNotificationParam& p_param); // vtable+0x58 + virtual void HandlePresenter(MxNotificationParam& p_param); // vtable+0x5c + virtual void AdvanceSerialAction(MxPresenter* p_presenter); // vtable+0x60 // FUNCTION: LEGO1 0x1000caf0 - virtual MxBool VTable0x64(undefined4 p_undefined) + virtual MxBool GetActionEnded(undefined4 p_undefined) { if (m_compositePresenter) { - return m_compositePresenter->VTable0x64(p_undefined); + return m_compositePresenter->GetActionEnded(p_undefined); } return TRUE; } // vtable+0x64 diff --git a/LEGO1/omni/include/mxvideomanager.h b/LEGO1/omni/include/mxvideomanager.h index 3e3266aa..ed5fdb81 100644 --- a/LEGO1/omni/include/mxvideomanager.h +++ b/LEGO1/omni/include/mxvideomanager.h @@ -62,7 +62,7 @@ class MxVideoManager : public MxPresentationManager { LPDIRECT3D2 m_pDirect3D; // 0x54 MxDisplaySurface* m_displaySurface; // 0x58 MxRegion* m_region; // 0x5c - MxBool m_unk0x60; // 0x60 + MxBool m_created; // 0x60 }; #endif // MXVIDEOMANAGER_H diff --git a/LEGO1/omni/src/common/mxcompositepresenter.cpp b/LEGO1/omni/src/common/mxcompositepresenter.cpp index b3d56875..ca8f32cd 100644 --- a/LEGO1/omni/src/common/mxcompositepresenter.cpp +++ b/LEGO1/omni/src/common/mxcompositepresenter.cpp @@ -117,10 +117,10 @@ MxLong MxCompositePresenter::Notify(MxParam& p_param) switch (param.GetNotification()) { case c_notificationEndAction: - VTable0x58((MxEndActionNotificationParam&) p_param); + HandleEndAction((MxEndActionNotificationParam&) p_param); break; case c_notificationPresenter: - VTable0x5c((MxNotificationParam&) p_param); + HandlePresenter((MxNotificationParam&) p_param); break; default: assert(0); @@ -131,7 +131,7 @@ MxLong MxCompositePresenter::Notify(MxParam& p_param) } // FUNCTION: LEGO1 0x100b67f0 -void MxCompositePresenter::VTable0x58(MxEndActionNotificationParam& p_param) +void MxCompositePresenter::HandleEndAction(MxEndActionNotificationParam& p_param) { MxPresenter* presenter = (MxPresenter*) p_param.GetSender(); MxDSAction* action = p_param.GetAction(); @@ -177,7 +177,7 @@ void MxCompositePresenter::VTable0x58(MxEndActionNotificationParam& p_param) } // FUNCTION: LEGO1 0x100b69b0 -void MxCompositePresenter::VTable0x5c(MxNotificationParam& p_param) +void MxCompositePresenter::HandlePresenter(MxNotificationParam& p_param) { if (!m_list.empty()) { MxPresenter* presenter = (MxPresenter*) p_param.GetSender(); @@ -218,13 +218,13 @@ void MxCompositePresenter::VTable0x5c(MxNotificationParam& p_param) } // FUNCTION: LEGO1 0x100b6b40 -void MxCompositePresenter::VTable0x60(MxPresenter* p_presenter) +void MxCompositePresenter::AdvanceSerialAction(MxPresenter* p_presenter) { for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { if (*it == p_presenter) { if (++it == m_list.end()) { if (m_compositePresenter) { - m_compositePresenter->VTable0x60(this); + m_compositePresenter->AdvanceSerialAction(this); } } else if (m_action->IsA("MxDSSerialAction")) { diff --git a/LEGO1/omni/src/common/mxmediapresenter.cpp b/LEGO1/omni/src/common/mxmediapresenter.cpp index 0dbb1d3b..76806143 100644 --- a/LEGO1/omni/src/common/mxmediapresenter.cpp +++ b/LEGO1/omni/src/common/mxmediapresenter.cpp @@ -156,7 +156,8 @@ void MxMediaPresenter::EndAction() m_currentChunk = NULL; - if (m_action->GetFlags() & MxDSAction::c_world && (!m_compositePresenter || !m_compositePresenter->VTable0x64(2))) { + if (m_action->GetFlags() & MxDSAction::c_world && + (!m_compositePresenter || !m_compositePresenter->GetActionEnded(2))) { MxPresenter::Enable(FALSE); SetTickleState(e_idle); } diff --git a/LEGO1/omni/src/video/mxstillpresenter.cpp b/LEGO1/omni/src/video/mxstillpresenter.cpp index 53a0427a..820f8b26 100644 --- a/LEGO1/omni/src/video/mxstillpresenter.cpp +++ b/LEGO1/omni/src/video/mxstillpresenter.cpp @@ -134,7 +134,7 @@ void MxStillPresenter::StreamingTickle() ProgressTickleState(e_repeating); if (m_action->GetDuration() == -1 && m_compositePresenter) { - m_compositePresenter->VTable0x60(this); + m_compositePresenter->AdvanceSerialAction(this); } } } diff --git a/LEGO1/omni/src/video/mxvideomanager.cpp b/LEGO1/omni/src/video/mxvideomanager.cpp index 40078e66..5fed2946 100644 --- a/LEGO1/omni/src/video/mxvideomanager.cpp +++ b/LEGO1/omni/src/video/mxvideomanager.cpp @@ -43,7 +43,7 @@ MxResult MxVideoManager::Init() m_displaySurface = NULL; m_region = NULL; m_videoParam.SetPalette(NULL); - m_unk0x60 = FALSE; + m_created = FALSE; return SUCCESS; } @@ -73,7 +73,7 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor) delete m_videoParam.GetPalette(); } - if (m_unk0x60) { + if (m_created) { if (m_pDirectDraw) { m_pDirectDraw->Release(); } @@ -154,7 +154,7 @@ MxResult MxVideoManager::VTable0x28( MxBool locked = FALSE; MxResult status = FAILURE; - m_unk0x60 = FALSE; + m_created = FALSE; if (MxPresentationManager::Create() != SUCCESS) { goto done; @@ -229,7 +229,7 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, MxResult status = FAILURE; HWND hWnd = NULL; - m_unk0x60 = TRUE; + m_created = TRUE; if (MxPresentationManager::Create() != SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxPresentationManager::Create failed"); diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index 3841783f..2bf03b52 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -123,7 +123,7 @@ class Vector4 : public Vector3 { Vector4(float* p_data) : Vector3(p_data) {} // Some code initializes a Vector4 from a `const float*` source. - // Example: `LegoCarBuild::VTable0x6c` + // Example: `LegoCarBuild::CheckIntersections` // Vector4 however is a class that can mutate its underlying source, making // initialization with a const source fundamentally incompatible. // BETA10 appears to have two separate constructors for Vector4 as well, diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..0ea419d7 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,63 @@ +# LEGO Island File Format Documentation + +This folder contains documentation for LEGO Island's custom binary file formats using [Kaitai Struct](https://kaitai.io/), a declarative language for describing binary data structures. + +## What is Kaitai Struct? + +Kaitai Struct allows you to define binary formats in a YAML-based `.ksy` file, which can then be: +- Compiled into parser libraries for [many programming languages](https://kaitai.io/#quick-start) (C++, Python, JavaScript, etc.) +- Visualized interactively using the [Kaitai Struct Visualizer](https://github.com/kaitai-io/kaitai_struct_visualizer) +- Dumped to human-readable formats using `ksdump` + +image + +## Documented Formats + +| File | Extension | Description | +|------|-----------|-------------| +| [`savegame.ksy`](/docs/savegame.ksy) | `.GS` | Main game save data (game state, progress, customizations) | +| [`players.ksy`](/docs/players.ksy) | `.gsi` | Player profile save data (usernames) | +| [`history.ksy`](/docs/history.ksy) | `.gsi` | Score history and high scores | + +## Using the Tools + +### Installation + +See the [Kaitai Struct Visualizer installation instructions](https://github.com/kaitai-io/kaitai_struct_visualizer?tab=readme-ov-file#downloading-and-installing) for setup details. + +### Kaitai Struct Visualizer (ksv) + +The [Kaitai Struct Visualizer](https://github.com/kaitai-io/kaitai_struct_visualizer) (`ksv`) provides an interactive terminal UI for exploring binary files. + +```bash +# View a save game file +ksv samples/G0.GS savegame.ksy + +# View a Players.gsi file +ksv samples/Players.gsi players.ksy + +# View a History.gsi file +ksv samples/History.gsi history.ksy +``` + +### Kaitai Struct Dump (ksdump) + +`ksdump` outputs the parsed structure as JSON or YAML for scripting and inspection. + +```bash +# Dump a save game to JSON +ksdump --format json samples/G0.GS savegame.ksy + +# Dump Players.gsi to JSON +ksdump --format json samples/Players.gsi players.ksy + +# Dump History.gsi to YAML +ksdump --format yaml samples/History.gsi history.ksy +``` + +## Sample Files + +The [`samples/`](/docs/samples/) directory contains example save files for testing: +- `G0.GS`, `G1.GS`, `G2.GS` - Sample main game save files (slots 0, 1, 2) +- `Players.gsi` - Sample player profile data +- `History.gsi` - Sample score history data diff --git a/docs/history.ksy b/docs/history.ksy new file mode 100644 index 00000000..f60bb2af --- /dev/null +++ b/docs/history.ksy @@ -0,0 +1,125 @@ +meta: + id: history + title: Score History Save File + application: LEGO Island + file-extension: gsi + license: CC0-1.0 + endian: le +doc: | + Score history save data for LEGO Island (1997). Stores up to 20 player + score entries, tracking high scores across all missions and characters. + + The file is located at `/History.gsi` where save_path is + typically the game's installation directory. + +seq: + - id: next_player_id + type: s2 + doc: | + The next player ID to be assigned when a new player profile is created. + Increments each time a new player is added, ensuring unique IDs. + - id: count + type: s2 + doc: Number of score entries in the history (0-20 max). + - id: entries + type: score_entry + repeat: expr + repeat-expr: count + doc: Array of score history entries, sorted by total score descending. + +types: + score_entry: + doc: | + A single score history entry containing a player's high scores across + all minigames and characters. Total serialized size is 45 bytes + (2 for index + 43 for score_item data). + seq: + - id: index + type: s2 + doc: Array index of this entry (0 to count-1). Stored redundantly in file. + - id: total_score + type: s2 + doc: Sum of all individual high scores across all missions and actors. + - id: scores + type: mission_scores + doc: High scores organized by mission type, each containing scores per actor. + - id: name + type: username + doc: The player's username associated with these scores. + - id: player_id + type: s2 + doc: Unique player identifier matching the player's profile. + + mission_scores: + doc: | + High scores for all 5 missions. Each mission contains scores for all + 5 playable actors. + seq: + - id: car_race + type: actor_scores + doc: Car Race mission high scores. + - id: jetski_race + type: actor_scores + doc: Jetski Race mission high scores. + - id: pizza_delivery + type: actor_scores + doc: Pizza Delivery mission high scores. + - id: tow_track + type: actor_scores + doc: Tow Track mission high scores. + - id: ambulance + type: actor_scores + doc: Ambulance mission high scores. + + actor_scores: + doc: | + High scores for a single mission across all 5 playable actors. + seq: + - id: pepper + type: u1 + enum: score_color + doc: High score for Pepper. + - id: mama + type: u1 + enum: score_color + doc: High score for Mama. + - id: papa + type: u1 + enum: score_color + doc: High score for Papa. + - id: nick + type: u1 + enum: score_color + doc: High score for Nick. + - id: laura + type: u1 + enum: score_color + doc: High score for Laura. + + username: + doc: | + A player username consisting of up to 7 letters. Each letter is stored + as a signed 16-bit index. The struct is always 14 bytes (0x0e). + seq: + - id: letters + type: s2 + repeat: expr + repeat-expr: 7 + doc: | + Letter indices for the username characters: + - 0-25: Standard alphabet (0=A, 1=B, ..., 25=Z) + - 29: International ä, å, or ñ (language-dependent) + - 30: International ö or æ (language-dependent) + - 31: International ß or ø (language-dependent) + - 32: International ü + - -1 (0xFFFF): Empty/unused position + + Unused positions are filled with -1. A name shorter than 7 + characters will have trailing -1 values. + +enums: + score_color: + 0: grey + 1: yellow + 2: blue + 3: red diff --git a/docs/players.ksy b/docs/players.ksy new file mode 100644 index 00000000..84136ed2 --- /dev/null +++ b/docs/players.ksy @@ -0,0 +1,48 @@ +meta: + id: players + title: Players Save File + application: LEGO Island + file-extension: gsi + license: CC0-1.0 + endian: le +doc: | + Player profile save data for LEGO Island (1997). Stores up to 9 player + profiles, each identified by a 7-character username. Usernames are stored + as letter indices rather than ASCII characters. + + The file is located at `/Players.gsi` where save_path is + typically the game's installation directory. + +seq: + - id: count + type: s2 + doc: | + Number of saved player profiles. The game supports a maximum of 9 + players; when a 10th player is added, the oldest profile is deleted. + - id: entries + type: username + repeat: expr + repeat-expr: count + doc: Array of player username entries, ordered by most recently played. + +types: + username: + doc: | + A player username consisting of up to 7 letters. Each letter is stored + as a signed 16-bit index. The struct is always 14 bytes (0x0e). + seq: + - id: letters + type: s2 + repeat: expr + repeat-expr: 7 + doc: | + Letter indices for the username characters: + - 0-25: Standard alphabet (0=A, 1=B, ..., 25=Z) + - 29: International ä, å, or ñ (language-dependent) + - 30: International ö or æ (language-dependent) + - 31: International ß or ø (language-dependent) + - 32: International ü + - -1 (0xFFFF): Empty/unused position + + Unused positions are filled with -1. A name shorter than 7 + characters will have trailing -1 values. diff --git a/docs/samples/G0.GS b/docs/samples/G0.GS new file mode 100755 index 00000000..205f5b8d Binary files /dev/null and b/docs/samples/G0.GS differ diff --git a/docs/samples/G1.GS b/docs/samples/G1.GS new file mode 100755 index 00000000..1db5a4e7 Binary files /dev/null and b/docs/samples/G1.GS differ diff --git a/docs/samples/G2.GS b/docs/samples/G2.GS new file mode 100755 index 00000000..2d941eff Binary files /dev/null and b/docs/samples/G2.GS differ diff --git a/docs/samples/History.gsi b/docs/samples/History.gsi new file mode 100755 index 00000000..f253055f Binary files /dev/null and b/docs/samples/History.gsi differ diff --git a/docs/samples/Players.gsi b/docs/samples/Players.gsi new file mode 100755 index 00000000..21c08e1d Binary files /dev/null and b/docs/samples/Players.gsi differ diff --git a/docs/savegame.ksy b/docs/savegame.ksy new file mode 100644 index 00000000..f08d5c22 --- /dev/null +++ b/docs/savegame.ksy @@ -0,0 +1,1014 @@ +meta: + id: savegame + title: Main Save Game File + application: LEGO Island + file-extension: gs + license: CC0-1.0 + endian: le +doc: | + Main save game file format for LEGO Island (1997). Stores complete game + progress including customization, mission scores, and world state. + + The file is located at `/G.GS` where slot is 0-9 and + save_path is typically the game's installation directory. + + File structure: + 1. Header (version, player ID, act, actor) + 2. Variables section (vehicle colors, background color, light position) + 3. Character manager data (66 actors) + 4. Plant manager data (81 plants) + 5. Building manager data (16 buildings) + 6. Game states (mission progress, scores, etc.) + 7. Previous area (for Act 2/3 saves) + +seq: + - id: version + type: s4 + doc: | + File format version. Must be 0x1000c (65548) for valid saves. + The game rejects files with mismatched versions. + - id: player_id + type: s2 + doc: Current player's unique ID from the player profile. + - id: current_act + type: u2 + enum: act + doc: Current game act (0 = Act 1, 1 = Act 2, 2 = Act 3). + - id: actor_id + type: u1 + enum: actor + doc: Currently selected playable character. + - id: variables + type: variable + repeat: until + repeat-until: _.is_end_marker + doc: | + Vehicle customization colors and game settings. Contains 43 color + variables, background color, light position, and ends with + "END_OF_VARIABLES" marker. + - id: characters + type: character_manager + doc: Character manager data for all 66 actors in the game. + - id: plants + type: plant_entry + repeat: expr + repeat-expr: 81 + doc: Plant manager data for all 81 plants in the game world. + - id: buildings + type: building_entry + repeat: expr + repeat-expr: 16 + doc: Building manager data for all 16 buildings in the game world. + - id: building_next_variant + type: u1 + doc: Next building variant to use (cycles through variants). + - id: state_count + type: s2 + doc: Number of serialized game states that follow. + - id: states + type: game_state + repeat: expr + repeat-expr: state_count + doc: Serialized game state objects (mission progress, scores, etc.). + - id: previous_area + type: s2 + doc: | + Previous area ID for Act 2/3 saves. Set to -1 (undefined) for Act 1. + Used to restore the player's location when loading a save. + +types: + variable: + doc: | + A named variable with a string value. Used for vehicle colors and + game settings. The "END_OF_VARIABLES" marker has no value. + seq: + - id: name_length + type: u1 + doc: Length of variable name in bytes. + - id: name + type: str + size: name_length + encoding: ASCII + doc: Variable name (e.g., "c_dbbkfny0", "backgroundcolor"). + - id: value_length + type: u1 + if: not is_end_marker + doc: Length of variable value in bytes. + - id: value + type: str + size: value_length + encoding: ASCII + if: not is_end_marker + doc: | + Variable value. For colors this is a color name like "lego red". + For backgroundcolor this is "set R G B". + For lightposition this is a number "1" or "2". + instances: + is_end_marker: + value: name == "END_OF_VARIABLES" + doc: True if this is the end-of-variables marker. + + character_manager: + doc: | + All 66 character entries in the game, in the order defined by g_actorInfoInit. + Each entry is 16 bytes, for a total of 1056 bytes. + seq: + - id: pepper + type: pepper_character_entry + doc: Pepper Roni + - id: mama + type: standard_character_entry + doc: Mama Brickolini + - id: papa + type: standard_character_entry + doc: Papa Brickolini + - id: nick + type: standard_character_entry + doc: Nick Brick + - id: laura + type: standard_character_entry + doc: Laura Brick + - id: infoman + type: infoman_character_entry + doc: Infomaniac + - id: brickstr + type: standard_character_entry + doc: Brickster + - id: studs + type: standard_character_entry + doc: Studs Linkin + - id: rhoda + type: standard_character_entry + doc: Rhoda Hogg + - id: valerie + type: standard_character_entry + doc: Valerie Stubbins + - id: snap + type: standard_character_entry + doc: Snap Lockitt + - id: pt + type: standard_character_entry + - id: mg + type: standard_character_entry + doc: Margaret Patricia "Maggie" Post + - id: bu + type: standard_character_entry + - id: ml + type: standard_character_entry + - id: nu + type: standard_character_entry + - id: na + type: standard_character_entry + doc: Nancy Nubbins + - id: cl + type: standard_character_entry + - id: en + type: standard_character_entry + - id: re + type: standard_character_entry + - id: ro + type: standard_character_entry + - id: d1 + type: standard_character_entry + - id: d2 + type: standard_character_entry + - id: d3 + type: standard_character_entry + - id: d4 + type: standard_character_entry + - id: l1 + type: standard_character_entry + - id: l2 + type: standard_character_entry + - id: l3 + type: standard_character_entry + - id: l4 + type: standard_character_entry + - id: l5 + type: standard_character_entry + - id: l6 + type: standard_character_entry + - id: b1 + type: standard_character_entry + - id: b2 + type: standard_character_entry + - id: b3 + type: standard_character_entry + - id: b4 + type: standard_character_entry + - id: cm + type: standard_character_entry + - id: gd + type: standard_character_entry + - id: rd + type: standard_character_entry + - id: pg + type: standard_character_entry + doc: Polly Gone + - id: bd + type: standard_character_entry + - id: sy + type: standard_character_entry + - id: gn + type: standard_character_entry + - id: df + type: standard_character_entry + - id: bs + type: standard_character_entry + - id: lt + type: standard_character_entry + - id: st + type: standard_character_entry + - id: bm + type: standard_character_entry + - id: jk + type: standard_character_entry + - id: ghost + type: ghost_character_entry + - id: ghost01 + type: ghost_character_entry + - id: ghost02 + type: ghost_character_entry + - id: ghost03 + type: ghost_character_entry + - id: ghost04 + type: ghost_character_entry + - id: ghost05 + type: ghost_character_entry + - id: hg + type: standard_character_entry + - id: pntgy + type: standard_character_entry + - id: pep + type: pepper_character_entry + - id: cop01 + type: standard_character_entry + - id: actor_01 + type: standard_character_entry + - id: actor_02 + type: standard_character_entry + - id: actor_03 + type: standard_character_entry + - id: actor_04 + type: standard_character_entry + - id: actor_05 + type: standard_character_entry + - id: btmncycl + type: standard_character_entry + - id: cboycycl + type: standard_character_entry + - id: boatman + type: standard_character_entry + + standard_character_entry: + doc: | + Character customization and state for actors using the standard hat parts + (g_hatPartIndices). Hat index 0-19 maps directly to hat_part enum. + Total size is 16 bytes. + seq: + - id: sound + type: s4 + doc: Sound/voice variant index. + - id: move + type: s4 + doc: Movement/animation variant index. + - id: mood + type: u1 + doc: Character mood state. + - id: hat_part_name_index + type: u1 + enum: standard_hat + doc: Index into standard hat parts (0-19 = standard hats). + - id: hat_name_index + type: u1 + enum: lego_color + doc: Hat color. + - id: infogron_name_index + type: u1 + enum: lego_color + doc: Torso (infogron) color. + - id: armlft_name_index + type: u1 + enum: lego_color + doc: Left arm color. + - id: armrt_name_index + type: u1 + enum: lego_color + doc: Right arm color. + - id: leglft_name_index + type: u1 + enum: lego_color + doc: Left leg color. + - id: legrt_name_index + type: u1 + enum: lego_color + doc: Right leg color. + + pepper_character_entry: + doc: | + Character customization and state for Pepper (uses g_pepperHatPartIndices). + Hat index 0=phat, 1-20 map to standard hats 0-19. + Total size is 16 bytes. + seq: + - id: sound + type: s4 + doc: Sound/voice variant index. + - id: move + type: s4 + doc: Movement/animation variant index. + - id: mood + type: u1 + doc: Character mood state. + - id: hat_part_name_index + type: u1 + enum: pepper_hat + doc: Index into Pepper's hat parts (0=phat, 1-20=standard hats 0-19). + - id: hat_name_index + type: u1 + enum: lego_color + doc: Hat color. + - id: infogron_name_index + type: u1 + enum: lego_color + doc: Torso (infogron) color. + - id: armlft_name_index + type: u1 + enum: lego_color + doc: Left arm color. + - id: armrt_name_index + type: u1 + enum: lego_color + doc: Right arm color. + - id: leglft_name_index + type: u1 + enum: lego_color + doc: Left leg color. + - id: legrt_name_index + type: u1 + enum: lego_color + doc: Right leg color. + + infoman_character_entry: + doc: | + Character customization and state for Infoman (uses g_infomanHatPartIndices). + Hat index 0=icap (only option). + Total size is 16 bytes. + seq: + - id: sound + type: s4 + doc: Sound/voice variant index. + - id: move + type: s4 + doc: Movement/animation variant index. + - id: mood + type: u1 + doc: Character mood state. + - id: hat_part_name_index + type: u1 + enum: infoman_hat_index + doc: Index into Infoman's hat parts (0=icap only). + - id: hat_name_index + type: u1 + enum: lego_color + doc: Hat color. + - id: infogron_name_index + type: u1 + enum: lego_color + doc: Torso (infogron) color. + - id: armlft_name_index + type: u1 + enum: lego_color + doc: Left arm color. + - id: armrt_name_index + type: u1 + enum: lego_color + doc: Right arm color. + - id: leglft_name_index + type: u1 + enum: lego_color + doc: Left leg color. + - id: legrt_name_index + type: u1 + enum: lego_color + doc: Right leg color. + + ghost_character_entry: + doc: | + Character customization and state for ghosts (uses g_ghostHatPartIndices). + Hat index 0=sheet (only option). + Total size is 16 bytes. + seq: + - id: sound + type: s4 + doc: Sound/voice variant index. + - id: move + type: s4 + doc: Movement/animation variant index. + - id: mood + type: u1 + doc: Character mood state. + - id: hat_part_name_index + type: u1 + enum: ghost_hat_index + doc: Index into ghost hat parts (0=sheet only). + - id: hat_name_index + type: u1 + enum: lego_color + doc: Hat color. + - id: infogron_name_index + type: u1 + enum: lego_color + doc: Torso (infogron) color. + - id: armlft_name_index + type: u1 + enum: lego_color + doc: Left arm color. + - id: armrt_name_index + type: u1 + enum: lego_color + doc: Right arm color. + - id: leglft_name_index + type: u1 + enum: lego_color + doc: Left leg color. + - id: legrt_name_index + type: u1 + enum: lego_color + doc: Right leg color. + + plant_entry: + doc: | + Plant state data for a single plant in the game world. + Total size is 12 bytes per plant. + seq: + - id: variant + type: u1 + enum: plant_variant + doc: Plant type (flower, tree, bush, palm). + - id: sound + type: u4 + doc: Sound effect index when interacting. + - id: move + type: u4 + doc: Movement/animation state. + - id: mood + type: u1 + doc: Plant mood/state value. + - id: color + type: u1 + enum: plant_color + doc: Plant color variant. + - id: counter + type: s1 + doc: | + Growth/interaction counter. Affects plant height. + This is used in Act 2/3. + + building_entry: + doc: | + Building state data for a single building in the game world. + Total size is 10 bytes per building. + seq: + - id: sound + type: u4 + doc: Sound effect index. + - id: move + type: u4 + doc: Movement/animation state. + - id: mood + type: u1 + doc: Building mood/state value. + - id: counter + type: s1 + doc: | + Interaction counter. Affects building height adjustment. + This is used in Act 2/3. + + game_state: + doc: | + A serialized game state object. The name determines the type and + format of the data that follows. + seq: + - id: name_length + type: s2 + doc: Length of state class name. + - id: name + type: str + size: name_length + encoding: ASCII + doc: | + State class name (e.g., "Act1State", "PizzeriaState"). + Determines the format of the following data. + - id: data + type: + switch-on: name + cases: + '"PizzeriaState"': pizzeria_state_data + '"PizzaMissionState"': pizza_mission_state_data + '"TowTrackMissionState"': score_mission_state_data + '"AmbulanceMissionState"': score_mission_state_data + '"HospitalState"': hospital_state_data + '"GasStationState"': gas_station_state_data + '"PoliceState"': police_state_data + '"JetskiRaceState"': race_state_data + '"CarRaceState"': race_state_data + '"LegoJetskiBuildState"': vehicle_build_state_data + '"LegoCopterBuildState"': vehicle_build_state_data + '"LegoDuneCarBuildState"': vehicle_build_state_data + '"LegoRaceCarBuildState"': vehicle_build_state_data + '"AnimState"': anim_state_data + '"Act1State"': act1_state_data + doc: State-specific data. Format depends on state class name. + + pizzeria_state_data: + doc: | + Pizzeria state tracking playlist indices for each actor. + Total size is 10 bytes (5 x S16). + seq: + - id: pepper_playlist_index + type: s2 + doc: Pepper's next playlist index. + - id: mama_playlist_index + type: s2 + doc: Mama's next playlist index. + - id: papa_playlist_index + type: s2 + doc: Papa's next playlist index. + - id: nick_playlist_index + type: s2 + doc: Nick's next playlist index. + - id: laura_playlist_index + type: s2 + doc: Laura's next playlist index. + + pizza_mission_state_data: + doc: | + Pizza delivery mission state for all 5 actors. + Total size is 40 bytes (5 missions x 4 x S16). + seq: + - id: pepper + type: pizza_mission_entry + doc: Pepper's pizza delivery mission data. + - id: mama + type: pizza_mission_entry + doc: Mama's pizza delivery mission data. + - id: papa + type: pizza_mission_entry + doc: Papa's pizza delivery mission data. + - id: nick + type: pizza_mission_entry + doc: Nick's pizza delivery mission data. + - id: laura + type: pizza_mission_entry + doc: Laura's pizza delivery mission data. + + pizza_mission_entry: + doc: Single actor's pizza mission data (8 bytes). + seq: + - id: unk0x06 + type: s2 + doc: Unknown field at offset 0x06. + - id: counter + type: s2 + doc: Mission attempt counter. + - id: score + type: s2 + enum: score_color + doc: Current/last mission score. + - id: hi_score + type: s2 + enum: score_color + doc: High score for this mission. + + score_mission_state_data: + doc: | + Mission state with scores and high scores for all 5 actors. + Used by TowTrackMissionState and AmbulanceMissionState. + Total size is 20 bytes (10 x S16). + seq: + - id: pepper_score + type: s2 + enum: score_color + doc: Pepper's current/last score. + - id: mama_score + type: s2 + enum: score_color + doc: Mama's current/last score. + - id: papa_score + type: s2 + enum: score_color + doc: Papa's current/last score. + - id: nick_score + type: s2 + enum: score_color + doc: Nick's current/last score. + - id: laura_score + type: s2 + enum: score_color + doc: Laura's current/last score. + - id: pepper_high_score + type: s2 + enum: score_color + doc: Pepper's high score. + - id: mama_high_score + type: s2 + enum: score_color + doc: Mama's high score. + - id: papa_high_score + type: s2 + enum: score_color + doc: Papa's high score. + - id: nick_high_score + type: s2 + enum: score_color + doc: Nick's high score. + - id: laura_high_score + type: s2 + enum: score_color + doc: Laura's high score. + + hospital_state_data: + doc: | + Hospital interaction state for all actors. + Total size is 12 bytes (6 x S16). + seq: + - id: state_actor + type: s2 + doc: Current actor state. + - id: state_pepper + type: s2 + doc: Pepper's hospital interaction state. + - id: state_mama + type: s2 + doc: Mama's hospital interaction state. + - id: state_papa + type: s2 + doc: Papa's hospital interaction state. + - id: state_nick + type: s2 + doc: Nick's hospital interaction state. + - id: state_laura + type: s2 + doc: Laura's hospital interaction state. + + gas_station_state_data: + doc: | + Gas station interaction state for all actors. + Total size is 10 bytes (5 x S16). + seq: + - id: pepper_action + type: s2 + doc: Pepper's gas station action state. + - id: mama_action + type: s2 + doc: Mama's gas station action state. + - id: papa_action + type: s2 + doc: Papa's gas station action state. + - id: nick_action + type: s2 + doc: Nick's gas station action state. + - id: laura_action + type: s2 + doc: Laura's gas station action state. + + police_state_data: + doc: | + Police station state. Stores the police script ID. + Total size is 4 bytes (1 x S32). + seq: + - id: police_script + type: s4 + doc: Current police script/animation ID. + + race_state_data: + doc: | + Race state with scores for all 5 actors. + Used by JetskiRaceState and CarRaceState. + Total size is 25 bytes (5 entries x 5 bytes). + seq: + - id: pepper + type: race_entry + doc: Pepper's race scores. + - id: mama + type: race_entry + doc: Mama's race scores. + - id: papa + type: race_entry + doc: Papa's race scores. + - id: nick + type: race_entry + doc: Nick's race scores. + - id: laura + type: race_entry + doc: Laura's race scores. + + race_entry: + doc: Single actor's race score entry (5 bytes). + seq: + - id: id + type: u1 + enum: actor + doc: Actor ID. + - id: last_score + type: s2 + enum: score_color + doc: Score from last race. + - id: high_score + type: s2 + enum: score_color + doc: Best score (high score). + + vehicle_build_state_data: + doc: | + Vehicle build state tracking build progress. + Used by LegoJetskiBuildState, LegoCopterBuildState, + LegoDuneCarBuildState, and LegoRaceCarBuildState. + Total size is 4 bytes (4 x U8). + seq: + - id: introduction_counter + type: u1 + doc: Number of times intro has been shown. + - id: finished_build + type: u1 + doc: Whether vehicle build was completed (0/1). + - id: played_exit_script + type: u1 + doc: Whether exit animation has played (0/1). + - id: placed_part_count + type: u1 + doc: Number of parts placed during current build. + + anim_state_data: + doc: | + Animation manager state. Contains extra character ID and + two variable-length arrays for tracking animation states. + seq: + - id: extra_character_id + type: u4 + doc: Extra character ID. + - id: anim_count + type: u4 + doc: Number of animation entries in first array. + - id: anim_indices + type: u2 + repeat: expr + repeat-expr: anim_count + doc: Animation index values. + - id: location_flags_count + type: u4 + doc: Number of location flag entries. + - id: location_flags + type: u1 + repeat: expr + repeat-expr: location_flags_count + doc: Location flags for animation positions. + + act1_state_data: + doc: | + Act 1 state containing named plane data and textures. + Always contains exactly 7 named planes (for each vehicle type), + followed by conditional textures based on which planes have names, + and two final fields. + seq: + - id: motocycle_plane + type: named_plane + doc: Motorcycle spawn plane. + - id: bike_plane + type: named_plane + doc: Bike spawn plane. + - id: skateboard_plane + type: named_plane + doc: Skateboard spawn plane. + - id: helicopter_plane + type: named_plane + doc: Helicopter spawn plane. + - id: jetski_plane + type: named_plane + doc: Jetski spawn plane. + - id: dunebuggy_plane + type: named_plane + doc: Dune buggy spawn plane. + - id: racecar_plane + type: named_plane + doc: Racecar spawn plane. + - id: helicopter_textures + type: act1_texture + repeat: expr + repeat-expr: 3 + if: helicopter_plane.name_length > 0 + doc: Helicopter textures (windshield, left jet, right jet). + - id: jetski_textures + type: act1_texture + repeat: expr + repeat-expr: 2 + if: jetski_plane.name_length > 0 + doc: Jetski textures (front, windshield). + - id: dunebuggy_texture + type: act1_texture + if: dunebuggy_plane.name_length > 0 + doc: Dune buggy front texture. + - id: racecar_textures + type: act1_texture + repeat: expr + repeat-expr: 3 + if: racecar_plane.name_length > 0 + doc: Racecar textures (front, back, tail). + - id: cpt_click_dialogue_next_index + type: s2 + doc: Next dialogue index for Captain Click. + - id: played_exit_explanation + type: u1 + doc: Whether exit explanation has been played (0/1). + + act1_texture: + doc: | + A texture used for customizable surfaces in Act 1. + Contains filename and LegoImage bitmap data. + seq: + - id: name_length + type: s2 + doc: Length of texture filename. + - id: name + type: str + size: name_length + encoding: ASCII + doc: Texture filename (e.g., "chwind.gif"). + - id: width + type: u4 + doc: Image width in pixels. + - id: height + type: u4 + doc: Image height in pixels. + - id: palette_count + type: u4 + doc: Number of palette entries. + - id: palette + type: palette_entry + repeat: expr + repeat-expr: palette_count + doc: Palette entries (RGB values). + - id: bitmap_data + size: width * height + doc: Raw pixel data (1 byte per pixel, indexed). + + palette_entry: + doc: A single RGB palette entry. + seq: + - id: red + type: u1 + doc: Red component (0-255). + - id: green + type: u1 + doc: Green component (0-255). + - id: blue + type: u1 + doc: Blue component (0-255). + + named_plane: + doc: | + A named plane used for actor positioning in Act 1. + Total size is variable: 2 + name_length + 36 bytes. + seq: + - id: name_length + type: s2 + doc: Length of plane name (S16 format like other strings). + - id: name + type: str + size: name_length + encoding: ASCII + doc: Plane name identifier (e.g., "INT43", "EDG02_51"). + - id: position + type: f4 + repeat: expr + repeat-expr: 3 + doc: Position vector (X, Y, Z). + - id: direction + type: f4 + repeat: expr + repeat-expr: 3 + doc: Direction/forward vector (X, Y, Z). + - id: up + type: f4 + repeat: expr + repeat-expr: 3 + doc: Up vector (X, Y, Z). + +enums: + act: + 0: act1 + 1: act2 + 2: act3 + + actor: + 0: none + 1: pepper + 2: mama + 3: papa + 4: nick + 5: laura + + plant_variant: + 0: flower + 1: tree + 2: bush + 3: palm + + plant_color: + 0: white + 1: black + 2: yellow + 3: red + 4: green + + lego_color: + 0: white + 1: black + 2: yellow + 3: red + 4: blue + 5: brown + 6: lt_grey + 7: green + + hat_part: + 0: baseball + 1: chef + 2: cap + 3: cophat + 4: helmet + 5: ponytail + 6: pageboy + 7: shrthair + 8: bald + 9: flower + 10: cboyhat + 11: cuphat + 12: cathat + 13: backbcap + 14: pizhat + 15: caprc + 16: capch + 17: capdb + 18: capjs + 19: capmd + 20: sheet + 21: phat + 22: icap + + standard_hat: + 0: baseball + 1: chef + 2: cap + 3: cophat + 4: helmet + 5: ponytail + 6: pageboy + 7: shrthair + 8: bald + 9: flower + 10: cboyhat + 11: cuphat + 12: cathat + 13: backbcap + 14: pizhat + 15: caprc + 16: capch + 17: capdb + 18: capjs + 19: capmd + + pepper_hat: + 0: phat + 1: baseball + 2: chef + 3: cap + 4: cophat + 5: helmet + 6: ponytail + 7: pageboy + 8: shrthair + 9: bald + 10: flower + 11: cboyhat + 12: cuphat + 13: cathat + 14: backbcap + 15: pizhat + 16: caprc + 17: capch + 18: capdb + 19: capjs + 20: capmd + + infoman_hat_index: + 0: icap + + ghost_hat_index: + 0: sheet + + score_color: + 0: grey + 1: yellow + 2: blue + 3: red