Merge remote-tracking branch 'upstream/master'

This commit is contained in:
olebeck 2025-08-10 12:26:25 +02:00
commit df743f901b
201 changed files with 3075 additions and 1813 deletions

View File

@ -35,8 +35,10 @@ jobs:
matrix: matrix:
include: include:
- { name: 'Linux', os: 'ubuntu-latest', generator: 'Ninja', dx5: false, config: true, linux: true, werror: true, clang-tidy: true } - { name: 'Linux', os: 'ubuntu-latest', generator: 'Ninja', dx5: false, config: true, linux: true, werror: true, clang-tidy: true }
- { name: 'Linux (Debug)', os: 'ubuntu-latest', generator: 'Ninja', dx5: false, config: true, linux: true, werror: true, clang-tidy: true, debug: true }
- { name: 'MSVC (x86)', os: 'windows-latest', generator: 'Ninja', dx5: true, config: false, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64_x86' } - { name: 'MSVC (x86)', os: 'windows-latest', generator: 'Ninja', dx5: true, config: false, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64_x86' }
- { name: 'MSVC (x64)', os: 'windows-latest', generator: 'Ninja', dx5: false, config: true, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64' } - { name: 'MSVC (x64)', os: 'windows-latest', generator: 'Ninja', dx5: false, config: true, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64' }
- { name: 'MSVC (x64 Debug)', os: 'windows-latest', generator: 'Ninja', dx5: false, config: true, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64', debug: true }
- { name: 'MSVC (arm64)', os: 'windows-latest', generator: 'Ninja', dx5: false, config: false, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64_arm64' } - { name: 'MSVC (arm64)', os: 'windows-latest', generator: 'Ninja', dx5: false, config: false, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64_arm64' }
- { name: 'msys2 mingw32', os: 'windows-latest', generator: 'Ninja', dx5: false, config: false, mingw: true, werror: true, clang-tidy: true, msystem: 'mingw32', msys-env: 'mingw-w64-i686', shell: 'msys2 {0}' } - { name: 'msys2 mingw32', os: 'windows-latest', generator: 'Ninja', dx5: false, config: false, mingw: true, werror: true, clang-tidy: true, msystem: 'mingw32', msys-env: 'mingw-w64-i686', shell: 'msys2 {0}' }
- { name: 'msys2 mingw64', os: 'windows-latest', generator: 'Ninja', dx5: false, config: true, mingw: true, werror: true, clang-tidy: true, msystem: 'mingw64', msys-env: 'mingw-w64-x86_64', shell: 'msys2 {0}' } - { name: 'msys2 mingw64', os: 'windows-latest', generator: 'Ninja', dx5: false, config: true, mingw: true, werror: true, clang-tidy: true, msystem: 'mingw64', msys-env: 'mingw-w64-x86_64', shell: 'msys2 {0}' }
@ -126,7 +128,7 @@ jobs:
-DISLE_BUILD_CONFIG=${{ !!matrix.config }} \ -DISLE_BUILD_CONFIG=${{ !!matrix.config }} \
-DENABLE_CLANG_TIDY=${{ !!matrix.clang-tidy }} \ -DENABLE_CLANG_TIDY=${{ !!matrix.clang-tidy }} \
-DISLE_WERROR=${{ !!matrix.werror }} \ -DISLE_WERROR=${{ !!matrix.werror }} \
-DISLE_DEBUG=OFF \ -DISLE_DEBUG=${{ matrix.debug || 'OFF' }} \
-Werror=dev -Werror=dev
- name: Build (CMake) - name: Build (CMake)

View File

@ -88,7 +88,7 @@ persistent=yes
# Minimum Python version to use for version dependent checks. Will default to # Minimum Python version to use for version dependent checks. Will default to
# the version used to run pylint. # the version used to run pylint.
py-version=3.11 py-version=3.12
# Discover python modules and packages in the file system subtree. # Discover python modules and packages in the file system subtree.
recursive=no recursive=no

View File

@ -14,7 +14,7 @@ endif()
if (EMSCRIPTEN) if (EMSCRIPTEN)
add_compile_options(-pthread) add_compile_options(-pthread)
add_link_options(-sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=2gb -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -sOFFSCREENCANVAS_SUPPORT=1 -sPTHREAD_POOL_SIZE_STRICT=0 -sFORCE_FILESYSTEM=1 -sWASMFS=1 -sEXIT_RUNTIME=1) add_link_options(-sUSE_WEBGL2=1 -sMIN_WEBGL_VERSION=2 -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=2gb -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -sOFFSCREENCANVAS_SUPPORT=1 -sPTHREAD_POOL_SIZE_STRICT=0 -sFORCE_FILESYSTEM=1 -sWASMFS=1 -sEXIT_RUNTIME=1)
set(SDL_PTHREADS ON CACHE BOOL "Enable SDL pthreads" FORCE) set(SDL_PTHREADS ON CACHE BOOL "Enable SDL pthreads" FORCE)
endif() endif()
@ -39,7 +39,7 @@ else()
endif() endif()
find_program(SDL_SHADERCROSS_BIN NAMES "shadercross") find_program(SDL_SHADERCROSS_BIN NAMES "shadercross")
find_package(Python3 3.11 COMPONENTS Interpreter) find_package(Python3 3.12 COMPONENTS Interpreter)
option(ISLE_BUILD_APP "Build isle application" ON) option(ISLE_BUILD_APP "Build isle application" ON)
option(ISLE_ASAN "Enable Address Sanitizer" OFF) option(ISLE_ASAN "Enable Address Sanitizer" OFF)
@ -184,6 +184,8 @@ target_include_directories(lego1 PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/L
target_link_libraries(lego1 PRIVATE SDL3::SDL3) target_link_libraries(lego1 PRIVATE SDL3::SDL3)
target_link_libraries(lego1 PUBLIC SDL3::Headers) target_link_libraries(lego1 PUBLIC SDL3::Headers)
target_link_libraries(lego1 PRIVATE $<$<BOOL:${ISLE_USE_DX5}>:DirectX5::DirectX5>) target_link_libraries(lego1 PRIVATE $<$<BOOL:${ISLE_USE_DX5}>:DirectX5::DirectX5>)
# Allow unconditional include of miniwin/miniwind3d.h
target_link_libraries(lego1 PRIVATE miniwin-headers)
if(WIN32) if(WIN32)
set_property(TARGET lego1 PROPERTY PREFIX "") set_property(TARGET lego1 PROPERTY PREFIX "")
endif() endif()
@ -314,10 +316,10 @@ target_sources(lego1 PRIVATE
LEGO1/omni/src/common/mxcompositepresenter.cpp LEGO1/omni/src/common/mxcompositepresenter.cpp
LEGO1/omni/src/common/mxcore.cpp LEGO1/omni/src/common/mxcore.cpp
LEGO1/omni/src/common/mxdebug.cpp LEGO1/omni/src/common/mxdebug.cpp
LEGO1/omni/src/common/mxmediamanager.cpp
LEGO1/omni/src/common/mxmediapresenter.cpp LEGO1/omni/src/common/mxmediapresenter.cpp
LEGO1/omni/src/common/mxmisc.cpp LEGO1/omni/src/common/mxmisc.cpp
LEGO1/omni/src/common/mxobjectfactory.cpp LEGO1/omni/src/common/mxobjectfactory.cpp
LEGO1/omni/src/common/mxpresentationmanager.cpp
LEGO1/omni/src/common/mxpresenter.cpp LEGO1/omni/src/common/mxpresenter.cpp
LEGO1/omni/src/common/mxstring.cpp LEGO1/omni/src/common/mxstring.cpp
LEGO1/omni/src/common/mxticklemanager.cpp LEGO1/omni/src/common/mxticklemanager.cpp
@ -328,7 +330,7 @@ target_sources(lego1 PRIVATE
LEGO1/omni/src/entity/mxentity.cpp LEGO1/omni/src/entity/mxentity.cpp
LEGO1/omni/src/event/mxeventmanager.cpp LEGO1/omni/src/event/mxeventmanager.cpp
LEGO1/omni/src/event/mxeventpresenter.cpp LEGO1/omni/src/event/mxeventpresenter.cpp
LEGO1/omni/src/main/mxomni.cpp LEGO1/omni/src/main/mxmain.cpp
LEGO1/omni/src/main/mxomnicreateflags.cpp LEGO1/omni/src/main/mxomnicreateflags.cpp
LEGO1/omni/src/main/mxomnicreateparam.cpp LEGO1/omni/src/main/mxomnicreateparam.cpp
LEGO1/omni/src/notify/mxactionnotificationparam.cpp LEGO1/omni/src/notify/mxactionnotificationparam.cpp
@ -463,9 +465,6 @@ target_sources(lego1 PRIVATE
LEGO1/lego/legoomni/src/race/raceskel.cpp LEGO1/lego/legoomni/src/race/raceskel.cpp
LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp
LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp
LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp
LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp
LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp
LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp
LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp
LEGO1/lego/legoomni/src/video/legopartpresenter.cpp LEGO1/lego/legoomni/src/video/legopartpresenter.cpp

View File

@ -13,6 +13,8 @@
#include <QKeyEvent> #include <QKeyEvent>
#include <QMessageBox> #include <QMessageBox>
#include <QProcess> #include <QProcess>
#include <SDL3/SDL.h>
#include <cmath>
#include <mxdirectx/legodxinfo.h> #include <mxdirectx/legodxinfo.h>
#include <ui_maindialog.h> #include <ui_maindialog.h>
@ -54,15 +56,18 @@ CMainDialog::CMainDialog(QWidget* pParent) : QDialog(pParent)
this, this,
&CMainDialog::OnRadiobuttonTextureHighQuality &CMainDialog::OnRadiobuttonTextureHighQuality
); );
connect(m_ui->windowedRadioButton, &QRadioButton::toggled, this, &CMainDialog::OnRadioWindowed);
connect(m_ui->fullscreenRadioButton, &QRadioButton::toggled, this, &CMainDialog::OnRadioFullscreen);
connect(m_ui->exFullscreenRadioButton, &QRadioButton::toggled, this, &CMainDialog::OnRadioExclusiveFullscreen);
connect(m_ui->devicesList, &QListWidget::currentRowChanged, this, &CMainDialog::OnList3DevicesSelectionChanged); connect(m_ui->devicesList, &QListWidget::currentRowChanged, this, &CMainDialog::OnList3DevicesSelectionChanged);
connect(m_ui->musicCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxMusic); connect(m_ui->musicCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxMusic);
connect(m_ui->sound3DCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckbox3DSound); connect(m_ui->sound3DCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckbox3DSound);
connect(m_ui->fullscreenCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxFullscreen);
connect(m_ui->exclusiveFullscreenCheckbox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxExclusiveFullscreen);
connect(m_ui->rumbleCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxRumble); connect(m_ui->rumbleCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxRumble);
connect(m_ui->textureCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxTexture); connect(m_ui->textureCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxTexture);
connect(m_ui->touchComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::TouchControlsChanged); connect(m_ui->touchComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::TouchControlsChanged);
connect(m_ui->transitionTypeComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::TransitionTypeChanged); connect(m_ui->transitionTypeComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::TransitionTypeChanged);
connect(m_ui->exFullResComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::ExclusiveResolutionChanged);
connect(m_ui->okButton, &QPushButton::clicked, this, &CMainDialog::accept); connect(m_ui->okButton, &QPushButton::clicked, this, &CMainDialog::accept);
connect(m_ui->cancelButton, &QPushButton::clicked, this, &CMainDialog::reject); connect(m_ui->cancelButton, &QPushButton::clicked, this, &CMainDialog::reject);
connect(m_ui->launchButton, &QPushButton::clicked, this, &CMainDialog::launch); connect(m_ui->launchButton, &QPushButton::clicked, this, &CMainDialog::launch);
@ -81,6 +86,11 @@ CMainDialog::CMainDialog(QWidget* pParent) : QDialog(pParent)
connect(m_ui->maxActorsSlider, &QSlider::valueChanged, this, &CMainDialog::MaxActorsChanged); connect(m_ui->maxActorsSlider, &QSlider::valueChanged, this, &CMainDialog::MaxActorsChanged);
connect(m_ui->maxActorsSlider, &QSlider::sliderMoved, this, &CMainDialog::MaxActorsChanged); connect(m_ui->maxActorsSlider, &QSlider::sliderMoved, this, &CMainDialog::MaxActorsChanged);
connect(m_ui->msaaSlider, &QSlider::valueChanged, this, &CMainDialog::MSAAChanged);
connect(m_ui->msaaSlider, &QSlider::sliderMoved, this, &CMainDialog::MSAAChanged);
connect(m_ui->AFSlider, &QSlider::valueChanged, this, &CMainDialog::AFChanged);
connect(m_ui->AFSlider, &QSlider::sliderMoved, this, &CMainDialog::AFChanged);
connect(m_ui->aspectRatioComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::AspectRatioChanged); connect(m_ui->aspectRatioComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::AspectRatioChanged);
connect(m_ui->xResSpinBox, &QSpinBox::valueChanged, this, &CMainDialog::XResChanged); connect(m_ui->xResSpinBox, &QSpinBox::valueChanged, this, &CMainDialog::XResChanged);
connect(m_ui->yResSpinBox, &QSpinBox::valueChanged, this, &CMainDialog::YResChanged); connect(m_ui->yResSpinBox, &QSpinBox::valueChanged, this, &CMainDialog::YResChanged);
@ -164,6 +174,23 @@ bool CMainDialog::OnInitDialog()
m_ui->maxActorsSlider->setValue(currentConfigApp->m_max_actors); m_ui->maxActorsSlider->setValue(currentConfigApp->m_max_actors);
m_ui->maxActorsNum->setNum(currentConfigApp->m_max_actors); m_ui->maxActorsNum->setNum(currentConfigApp->m_max_actors);
m_ui->exFullResComboBox->clear();
int displayModeCount;
displayModes = SDL_GetFullscreenDisplayModes(SDL_GetPrimaryDisplay(), &displayModeCount);
for (int i = 0; i < displayModeCount; ++i) {
QString mode =
QString("%1x%2 @ %3Hz").arg(displayModes[i]->w).arg(displayModes[i]->h).arg(displayModes[i]->refresh_rate);
m_ui->exFullResComboBox->addItem(mode);
if ((displayModes[i]->w == currentConfigApp->m_exf_x_res) &&
(displayModes[i]->h == currentConfigApp->m_exf_y_res) &&
(displayModes[i]->refresh_rate == currentConfigApp->m_exf_fps)) {
m_ui->exFullResComboBox->setCurrentIndex(i);
}
}
UpdateInterface(); UpdateInterface();
return true; return true;
} }
@ -258,18 +285,30 @@ void CMainDialog::UpdateInterface()
else { else {
m_ui->textureQualityHighRadioButton->setChecked(true); m_ui->textureQualityHighRadioButton->setChecked(true);
} }
if (currentConfigApp->m_exclusive_full_screen) {
m_ui->exFullscreenRadioButton->setChecked(true);
m_ui->resolutionBox->setEnabled(false);
m_ui->exFullResContainer->setEnabled(true);
}
else {
m_ui->resolutionBox->setEnabled(true);
m_ui->exFullResContainer->setEnabled(false);
if (currentConfigApp->m_full_screen) {
m_ui->fullscreenRadioButton->setChecked(true);
}
else {
m_ui->windowedRadioButton->setChecked(true);
}
}
m_ui->musicCheckBox->setChecked(currentConfigApp->m_music); m_ui->musicCheckBox->setChecked(currentConfigApp->m_music);
m_ui->fullscreenCheckBox->setChecked(currentConfigApp->m_full_screen);
m_ui->exclusiveFullscreenCheckbox->setEnabled(currentConfigApp->m_full_screen);
m_ui->exclusiveFullscreenCheckbox->setChecked(currentConfigApp->m_exclusive_full_screen);
m_ui->rumbleCheckBox->setChecked(currentConfigApp->m_haptic); m_ui->rumbleCheckBox->setChecked(currentConfigApp->m_haptic);
m_ui->touchComboBox->setCurrentIndex(currentConfigApp->m_touch_scheme); m_ui->touchComboBox->setCurrentIndex(currentConfigApp->m_touch_scheme);
m_ui->transitionTypeComboBox->setCurrentIndex(currentConfigApp->m_transition_type); m_ui->transitionTypeComboBox->setCurrentIndex(currentConfigApp->m_transition_type);
m_ui->dataPath->setText(QString::fromStdString(currentConfigApp->m_cd_path)); m_ui->dataPath->setText(QString::fromStdString(currentConfigApp->m_cd_path));
m_ui->savePath->setText(QString::fromStdString(currentConfigApp->m_save_path)); m_ui->savePath->setText(QString::fromStdString(currentConfigApp->m_save_path));
m_ui->textureCheckBox->setChecked(currentConfigApp->m_texture_load); m_ui->textureCheckBox->setChecked(currentConfigApp->m_texture_load);
m_ui->texturePath->setText(QString::fromStdString(currentConfigApp->m_texture_path)); m_ui->texturePath->setText(QString::fromStdString(currentConfigApp->m_texture_path));
m_ui->texturePath->setEnabled(currentConfigApp->m_texture_load); m_ui->texturePath->setEnabled(currentConfigApp->m_texture_load);
m_ui->texturePathOpen->setEnabled(currentConfigApp->m_texture_load); m_ui->texturePathOpen->setEnabled(currentConfigApp->m_texture_load);
@ -277,6 +316,15 @@ void CMainDialog::UpdateInterface()
m_ui->xResSpinBox->setValue(currentConfigApp->m_x_res); m_ui->xResSpinBox->setValue(currentConfigApp->m_x_res);
m_ui->yResSpinBox->setValue(currentConfigApp->m_y_res); m_ui->yResSpinBox->setValue(currentConfigApp->m_y_res);
m_ui->framerateSpinBox->setValue(static_cast<int>(std::round(1000.0f / currentConfigApp->m_frame_delta))); m_ui->framerateSpinBox->setValue(static_cast<int>(std::round(1000.0f / currentConfigApp->m_frame_delta)));
m_ui->maxLoDSlider->setValue((int) (currentConfigApp->m_max_lod * 10));
m_ui->LoDNum->setNum(currentConfigApp->m_max_lod);
m_ui->maxActorsSlider->setValue(currentConfigApp->m_max_actors);
m_ui->maxActorsNum->setNum(currentConfigApp->m_max_actors);
m_ui->msaaSlider->setValue(log2(currentConfigApp->m_msaa));
m_ui->msaaNum->setNum(currentConfigApp->m_msaa);
m_ui->AFSlider->setValue(log2(currentConfigApp->m_anisotropy));
m_ui->AFNum->setNum(currentConfigApp->m_anisotropy);
} }
// FUNCTION: CONFIG 0x004045e0 // FUNCTION: CONFIG 0x004045e0
@ -336,6 +384,42 @@ void CMainDialog::OnRadiobuttonTextureHighQuality(bool checked)
} }
} }
void CMainDialog::OnRadioWindowed(bool checked)
{
if (checked) {
currentConfigApp->m_full_screen = false;
currentConfigApp->m_exclusive_full_screen = false;
m_ui->resolutionBox->setEnabled(true);
m_ui->exFullResContainer->setEnabled(false);
m_modified = true;
UpdateInterface();
}
}
void CMainDialog::OnRadioFullscreen(bool checked)
{
if (checked) {
currentConfigApp->m_full_screen = true;
currentConfigApp->m_exclusive_full_screen = false;
m_ui->resolutionBox->setEnabled(true);
m_ui->exFullResContainer->setEnabled(false);
m_modified = true;
UpdateInterface();
}
}
void CMainDialog::OnRadioExclusiveFullscreen(bool checked)
{
if (checked) {
currentConfigApp->m_full_screen = true;
currentConfigApp->m_exclusive_full_screen = true;
m_ui->resolutionBox->setEnabled(false);
m_ui->exFullResContainer->setEnabled(true);
m_modified = true;
UpdateInterface();
}
}
// FUNCTION: CONFIG 0x004048c0 // FUNCTION: CONFIG 0x004048c0
void CMainDialog::OnCheckboxMusic(bool checked) void CMainDialog::OnCheckboxMusic(bool checked)
{ {
@ -344,21 +428,6 @@ void CMainDialog::OnCheckboxMusic(bool checked)
UpdateInterface(); UpdateInterface();
} }
void CMainDialog::OnCheckboxFullscreen(bool checked)
{
currentConfigApp->m_full_screen = checked;
m_ui->exclusiveFullscreenCheckbox->setEnabled(checked);
m_modified = true;
UpdateInterface();
}
void CMainDialog::OnCheckboxExclusiveFullscreen(bool checked)
{
currentConfigApp->m_exclusive_full_screen = checked;
m_modified = true;
UpdateInterface();
}
void CMainDialog::OnCheckboxRumble(bool checked) void CMainDialog::OnCheckboxRumble(bool checked)
{ {
currentConfigApp->m_haptic = checked; currentConfigApp->m_haptic = checked;
@ -387,6 +456,15 @@ void CMainDialog::TransitionTypeChanged(int index)
UpdateInterface(); UpdateInterface();
} }
void CMainDialog::ExclusiveResolutionChanged(int index)
{
currentConfigApp->m_exf_x_res = displayModes[index]->w;
currentConfigApp->m_exf_y_res = displayModes[index]->h;
currentConfigApp->m_exf_fps = displayModes[index]->refresh_rate;
m_modified = true;
UpdateInterface();
}
void CMainDialog::SelectDataPathDialog() void CMainDialog::SelectDataPathDialog()
{ {
QString data_path = QString::fromStdString(currentConfigApp->m_cd_path); QString data_path = QString::fromStdString(currentConfigApp->m_cd_path);
@ -458,15 +536,29 @@ void CMainDialog::SavePathEdited()
void CMainDialog::MaxLoDChanged(int value) void CMainDialog::MaxLoDChanged(int value)
{ {
currentConfigApp->m_max_lod = static_cast<float>(value) / 10.0f; currentConfigApp->m_max_lod = static_cast<float>(value) / 10.0f;
m_ui->LoDNum->setNum(value);
m_modified = true; m_modified = true;
UpdateInterface();
} }
void CMainDialog::MaxActorsChanged(int value) void CMainDialog::MaxActorsChanged(int value)
{ {
currentConfigApp->m_max_actors = value; currentConfigApp->m_max_actors = value;
m_ui->maxActorsNum->setNum(value);
m_modified = true; m_modified = true;
UpdateInterface();
}
void CMainDialog::MSAAChanged(int value)
{
currentConfigApp->m_msaa = exp2(value);
m_modified = true;
UpdateInterface();
}
void CMainDialog::AFChanged(int value)
{
currentConfigApp->m_anisotropy = exp2(value);
m_modified = true;
UpdateInterface();
} }
void CMainDialog::SelectTexturePathDialog() void CMainDialog::SelectTexturePathDialog()

View File

@ -7,6 +7,7 @@
#include <QDialog> #include <QDialog>
#include <QFileDialog> #include <QFileDialog>
#include <SDL3/SDL.h>
namespace Ui namespace Ui
{ {
@ -29,6 +30,7 @@ class CMainDialog : public QDialog {
bool m_modified = false; bool m_modified = false;
bool m_advanced = false; bool m_advanced = false;
Ui::MainDialog* m_ui = nullptr; Ui::MainDialog* m_ui = nullptr;
SDL_DisplayMode** displayModes;
void keyReleaseEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override;
bool OnInitDialog(); bool OnInitDialog();
@ -40,13 +42,15 @@ private slots:
void OnRadiobuttonModelHighQuality(bool checked); void OnRadiobuttonModelHighQuality(bool checked);
void OnRadiobuttonTextureLowQuality(bool checked); void OnRadiobuttonTextureLowQuality(bool checked);
void OnRadiobuttonTextureHighQuality(bool checked); void OnRadiobuttonTextureHighQuality(bool checked);
void OnRadioWindowed(bool checked);
void OnRadioFullscreen(bool checked);
void OnRadioExclusiveFullscreen(bool checked);
void OnCheckboxMusic(bool checked); void OnCheckboxMusic(bool checked);
void OnCheckboxFullscreen(bool checked);
void OnCheckboxExclusiveFullscreen(bool checked);
void OnCheckboxRumble(bool checked); void OnCheckboxRumble(bool checked);
void OnCheckboxTexture(bool checked); void OnCheckboxTexture(bool checked);
void TouchControlsChanged(int index); void TouchControlsChanged(int index);
void TransitionTypeChanged(int index); void TransitionTypeChanged(int index);
void ExclusiveResolutionChanged(int index);
void accept() override; void accept() override;
void reject() override; void reject() override;
void launch(); void launch();
@ -56,6 +60,8 @@ private slots:
void SavePathEdited(); void SavePathEdited();
void MaxLoDChanged(int value); void MaxLoDChanged(int value);
void MaxActorsChanged(int value); void MaxActorsChanged(int value);
void MSAAChanged(int value);
void AFChanged(int value);
void SelectTexturePathDialog(); void SelectTexturePathDialog();
void TexturePathEdited(); void TexturePathEdited();
void XResChanged(int i); void XResChanged(int i);

View File

@ -68,8 +68,9 @@ bool CConfigApp::InitInstance()
} }
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
m_aspect_ratio = 0; m_aspect_ratio = 0;
m_x_res = 640; m_exf_x_res = m_x_res = 640;
m_y_res = 480; m_exf_y_res = m_y_res = 480;
m_exf_fps = 60.00f;
m_frame_delta = 10.0f; m_frame_delta = 10.0f;
m_driver = NULL; m_driver = NULL;
m_device = NULL; m_device = NULL;
@ -83,6 +84,8 @@ bool CConfigApp::InitInstance()
m_3d_video_ram = FALSE; m_3d_video_ram = FALSE;
m_joystick_index = -1; m_joystick_index = -1;
m_display_bit_depth = 16; m_display_bit_depth = 16;
m_msaa = 1;
m_anisotropy = 1;
m_haptic = TRUE; m_haptic = TRUE;
m_touch_scheme = 2; m_touch_scheme = 2;
m_texture_load = TRUE; m_texture_load = TRUE;
@ -181,11 +184,16 @@ bool CConfigApp::ReadRegisterSettings()
m_joystick_index = iniparser_getint(dict, "isle:JoystickIndex", m_joystick_index); m_joystick_index = iniparser_getint(dict, "isle:JoystickIndex", m_joystick_index);
m_max_lod = iniparser_getdouble(dict, "isle:Max LOD", m_max_lod); m_max_lod = iniparser_getdouble(dict, "isle:Max LOD", m_max_lod);
m_max_actors = iniparser_getint(dict, "isle:Max Allowed Extras", m_max_actors); m_max_actors = iniparser_getint(dict, "isle:Max Allowed Extras", m_max_actors);
m_msaa = iniparser_getint(dict, "isle:MSAA", m_msaa);
m_anisotropy = iniparser_getint(dict, "isle:Anisotropic", m_anisotropy);
m_texture_load = iniparser_getboolean(dict, "extensions:texture loader", m_texture_load); m_texture_load = iniparser_getboolean(dict, "extensions:texture loader", m_texture_load);
m_texture_path = iniparser_getstring(dict, "texture loader:texture path", m_texture_path.c_str()); m_texture_path = iniparser_getstring(dict, "texture loader:texture path", m_texture_path.c_str());
m_aspect_ratio = iniparser_getint(dict, "isle:Aspect Ratio", m_aspect_ratio); m_aspect_ratio = iniparser_getint(dict, "isle:Aspect Ratio", m_aspect_ratio);
m_x_res = iniparser_getint(dict, "isle:Horizontal Resolution", m_x_res); m_x_res = iniparser_getint(dict, "isle:Horizontal Resolution", m_x_res);
m_y_res = iniparser_getint(dict, "isle:Vertical Resolution", m_y_res); m_y_res = iniparser_getint(dict, "isle:Vertical Resolution", m_y_res);
m_exf_x_res = iniparser_getint(dict, "isle:Exclusive X Resolution", m_exf_x_res);
m_exf_y_res = iniparser_getint(dict, "isle:Exclusive Y Resolution", m_exf_y_res);
m_exf_fps = iniparser_getdouble(dict, "isle:Exclusive Framerate", m_exf_fps);
m_frame_delta = iniparser_getdouble(dict, "isle:Frame Delta", m_frame_delta); m_frame_delta = iniparser_getdouble(dict, "isle:Frame Delta", m_frame_delta);
iniparser_freedict(dict); iniparser_freedict(dict);
return true; return true;
@ -259,6 +267,34 @@ bool CConfigApp::ValidateSettings()
m_touch_scheme = 2; m_touch_scheme = 2;
is_modified = TRUE; is_modified = TRUE;
} }
if (m_exclusive_full_screen && !m_full_screen) {
m_full_screen = TRUE;
is_modified = TRUE;
}
if (!(m_msaa & (m_msaa - 1))) { // Check if MSAA is power of 2 (1, 2, 4, 8, etc)
m_msaa = exp2(round(log2(m_msaa))); // Closest power of 2
is_modified = TRUE;
}
if (m_msaa > 16) {
m_msaa = 16;
is_modified = TRUE;
}
else if (m_msaa < 1) {
m_msaa = 1;
is_modified = TRUE;
}
if (!(m_anisotropy & (m_anisotropy - 1))) { // Check if anisotropy is power of 2 (1, 2, 4, 8, etc)
m_anisotropy = exp2(round(log2(m_anisotropy))); // Closest power of 2
is_modified = TRUE;
}
if (m_anisotropy > 16) {
m_anisotropy = 16;
is_modified = TRUE;
}
else if (m_anisotropy < 1) {
m_anisotropy = 1;
is_modified = TRUE;
}
return is_modified; return is_modified;
} }
@ -337,6 +373,8 @@ void CConfigApp::WriteRegisterSettings() const
iniparser_set(dict, "isle:savepath", m_save_path.c_str()); iniparser_set(dict, "isle:savepath", m_save_path.c_str());
SetIniInt(dict, "isle:Display Bit Depth", m_display_bit_depth); SetIniInt(dict, "isle:Display Bit Depth", m_display_bit_depth);
SetIniInt(dict, "isle:MSAA", m_msaa);
SetIniInt(dict, "isle:Anisotropic", m_anisotropy);
SetIniBool(dict, "isle:Flip Surfaces", m_flip_surfaces); SetIniBool(dict, "isle:Flip Surfaces", m_flip_surfaces);
SetIniBool(dict, "isle:Full Screen", m_full_screen); SetIniBool(dict, "isle:Full Screen", m_full_screen);
SetIniBool(dict, "isle:Exclusive Full Screen", m_exclusive_full_screen); SetIniBool(dict, "isle:Exclusive Full Screen", m_exclusive_full_screen);
@ -367,6 +405,9 @@ void CConfigApp::WriteRegisterSettings() const
SetIniInt(dict, "isle:Aspect Ratio", m_aspect_ratio); SetIniInt(dict, "isle:Aspect Ratio", m_aspect_ratio);
SetIniInt(dict, "isle:Horizontal Resolution", m_x_res); SetIniInt(dict, "isle:Horizontal Resolution", m_x_res);
SetIniInt(dict, "isle:Vertical Resolution", m_y_res); SetIniInt(dict, "isle:Vertical Resolution", m_y_res);
SetIniInt(dict, "isle:Exclusive X Resolution", m_exf_x_res);
SetIniInt(dict, "isle:Exclusive Y Resolution", m_exf_y_res);
iniparser_set(dict, "isle:Exclusive Framerate", std::to_string(m_exf_fps).c_str());
iniparser_set(dict, "isle:Frame Delta", std::to_string(m_frame_delta).c_str()); iniparser_set(dict, "isle:Frame Delta", std::to_string(m_frame_delta).c_str());
#undef SetIniBool #undef SetIniBool

View File

@ -62,11 +62,16 @@ class CConfigApp {
int m_aspect_ratio; int m_aspect_ratio;
int m_x_res; int m_x_res;
int m_y_res; int m_y_res;
int m_exf_x_res;
int m_exf_y_res;
float m_exf_fps;
float m_frame_delta; float m_frame_delta;
LegoDeviceEnumerate* m_device_enumerator; LegoDeviceEnumerate* m_device_enumerator;
MxDriver* m_driver; MxDriver* m_driver;
Direct3DDeviceInfo* m_device; Direct3DDeviceInfo* m_device;
int m_display_bit_depth; int m_display_bit_depth;
int m_msaa;
int m_anisotropy;
bool m_flip_surfaces; bool m_flip_surfaces;
bool m_full_screen; bool m_full_screen;
bool m_exclusive_full_screen; bool m_exclusive_full_screen;

View File

@ -56,6 +56,9 @@
<property name="scaledContents"> <property name="scaledContents">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="buddy">
<cstring>fullscreenRadioContainer_2</cstring>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -353,12 +356,18 @@ A higher setting will cause higher quality textures to be drawn regardless of di
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>15</width> <width>20</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize">
<size>
<width>20</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>35</string> <string>3.5</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -533,10 +542,16 @@ The game will gradually increase the number of actors until this maximum is reac
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>15</width> <width>20</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize">
<size>
<width>20</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>20</string> <string>20</string>
</property> </property>
@ -602,8 +617,59 @@ The game will gradually increase the number of actors until this maximum is reac
<property name="title"> <property name="title">
<string>General</string> <string>General</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_9">
<item row="0" column="1"> <item>
<widget class="QWidget" name="fullscreenRadioContainer_2" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:700;&quot;&gt;Windowed:&lt;/span&gt; Runs in a window, the initial resolution of which is dictated by Windowed Resolution. &lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:700;&quot;&gt;Fullscreen:&lt;/span&gt; Runs in a borderless window that consumes the entire screen. &lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:700;&quot;&gt;Exclusive Fullscreen:&lt;/span&gt; Grants the app full control of the display for better performance and lower input lag. May cause slower alt-tabbing.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<layout class="QVBoxLayout" name="fullscreenRadioContainer">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QRadioButton" name="windowedRadioButton">
<property name="text">
<string>Windowed</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="fullscreenRadioButton">
<property name="text">
<string>Fullscreen</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="exFullscreenRadioButton">
<property name="text">
<string>Exclusive Fullscreen</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QSpinBox" name="framerateSpinBox"> <widget class="QSpinBox" name="framerateSpinBox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Maximum framerate. Values above 100fps are untested.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Maximum framerate. Values above 100fps are untested.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -622,33 +688,6 @@ The game will gradually increase the number of actors until this maximum is reac
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<layout class="QVBoxLayout" name="fullscreenCheckboxContainer">
<item>
<widget class="QCheckBox" name="fullscreenCheckBox">
<property name="toolTip">
<string>Toggle fullscreen display mode.</string>
</property>
<property name="text">
<string>Fullscreen</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="exclusiveFullscreenCheckbox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Grants the app full control of the display for better performance and lower input lag. May cause slower alt-tabbing.</string>
</property>
<property name="text">
<string>Exclusive Fullscreen</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -765,17 +804,135 @@ The game will gradually increase the number of actors until this maximum is reac
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer_4"> <widget class="QGroupBox" name="exFullResContainer">
<property name="orientation"> <property name="enabled">
<enum>Qt::Orientation::Vertical</enum> <bool>false</bool>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="title">
<size> <string>Exclusive Fullscreen Resolution</string>
<width>20</width>
<height>40</height>
</size>
</property> </property>
</spacer> <layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QComboBox" name="exFullResComboBox">
<property name="placeholderText">
<string>Resolution</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="msaaAFBox" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="msaaBox">
<property name="title">
<string>MSAA</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSlider" name="msaaSlider">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>4</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TickPosition::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="msaaNum">
<property name="minimumSize">
<size>
<width>16</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>1</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="AFBox">
<property name="title">
<string>Anisotropic Filtering</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QSlider" name="AFSlider">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>4</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TickPosition::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="AFNum">
<property name="minimumSize">
<size>
<width>16</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>1</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -860,7 +1017,7 @@ The game will gradually increase the number of actors until this maximum is reac
<string>Settings for Texture Loader extension.</string> <string>Settings for Texture Loader extension.</string>
</property> </property>
<property name="title"> <property name="title">
<string>Texture Loader Extension</string> <string>Texture Loader</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
@ -1007,12 +1164,16 @@ The game will gradually increase the number of actors until this maximum is reac
<tabstop>maxLoDSlider</tabstop> <tabstop>maxLoDSlider</tabstop>
<tabstop>maxActorsSlider</tabstop> <tabstop>maxActorsSlider</tabstop>
<tabstop>devicesList</tabstop> <tabstop>devicesList</tabstop>
<tabstop>fullscreenCheckBox</tabstop> <tabstop>windowedRadioButton</tabstop>
<tabstop>exclusiveFullscreenCheckbox</tabstop> <tabstop>fullscreenRadioButton</tabstop>
<tabstop>exFullscreenRadioButton</tabstop>
<tabstop>framerateSpinBox</tabstop> <tabstop>framerateSpinBox</tabstop>
<tabstop>aspectRatioComboBox</tabstop> <tabstop>aspectRatioComboBox</tabstop>
<tabstop>xResSpinBox</tabstop> <tabstop>xResSpinBox</tabstop>
<tabstop>yResSpinBox</tabstop> <tabstop>yResSpinBox</tabstop>
<tabstop>exFullResComboBox</tabstop>
<tabstop>msaaSlider</tabstop>
<tabstop>AFSlider</tabstop>
<tabstop>touchComboBox</tabstop> <tabstop>touchComboBox</tabstop>
<tabstop>rumbleCheckBox</tabstop> <tabstop>rumbleCheckBox</tabstop>
<tabstop>textureCheckBox</tabstop> <tabstop>textureCheckBox</tabstop>

View File

@ -36,3 +36,11 @@ void Emscripten_SendPresenterProgress(MxDSAction* p_action, MxPresenter::TickleS
Emscripten_SendEvent("presenterProgress", buf); Emscripten_SendEvent("presenterProgress", buf);
} }
void Emscripten_SendExtensionProgress(const char* p_extension, MxU32 p_progress)
{
char buf[128];
SDL_snprintf(buf, sizeof(buf), "{\"name\": \"%s\", \"progress\": %d}", p_extension, p_progress);
Emscripten_SendEvent("extensionProgress", buf);
}

View File

@ -4,5 +4,6 @@
#include "mxpresenter.h" #include "mxpresenter.h"
void Emscripten_SendPresenterProgress(MxDSAction* p_action, MxPresenter::TickleState p_tickleState); void Emscripten_SendPresenterProgress(MxDSAction* p_action, MxPresenter::TickleState p_tickleState);
void Emscripten_SendExtensionProgress(const char* p_extension, MxU32 p_progress);
#endif // EMSCRIPTEN_EVENTS_H #endif // EMSCRIPTEN_EVENTS_H

View File

@ -1,8 +1,10 @@
#include "filesystem.h" #include "filesystem.h"
#include "events.h"
#include "extensions/textureloader.h"
#include "legogamestate.h" #include "legogamestate.h"
#include "misc.h" #include "misc.h"
#include "mxomni.h" #include "mxmain.h"
#include <SDL3/SDL_filesystem.h> #include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_log.h> #include <SDL3/SDL_log.h>
@ -13,6 +15,7 @@ static backend_t opfs = nullptr;
static backend_t fetchfs = nullptr; static backend_t fetchfs = nullptr;
extern const char* g_files[46]; extern const char* g_files[46];
extern const char* g_textures[120];
bool Emscripten_OPFSDisabled() bool Emscripten_OPFSDisabled()
{ {
@ -41,7 +44,7 @@ bool Emscripten_SetupConfig(const char* p_iniConfig)
void Emscripten_SetupFilesystem() void Emscripten_SetupFilesystem()
{ {
fetchfs = wasmfs_create_fetch_backend((MxString(Emscripten_streamHost) + MxString("/LEGO")).GetData(), 512 * 1024); fetchfs = wasmfs_create_fetch_backend((MxString(Emscripten_streamHost) + "/LEGO").GetData(), 512 * 1024);
wasmfs_create_directory("/LEGO", 0644, fetchfs); wasmfs_create_directory("/LEGO", 0644, fetchfs);
wasmfs_create_directory("/LEGO/Scripts", 0644, fetchfs); wasmfs_create_directory("/LEGO/Scripts", 0644, fetchfs);
@ -71,10 +74,41 @@ void Emscripten_SetupFilesystem()
} }
}; };
const auto preloadFile = [](const char* p_path) -> bool {
size_t length = 0;
void* data = SDL_LoadFile(p_path, &length);
if (data) {
SDL_free(data);
}
return length > 0;
};
for (const char* file : g_files) { for (const char* file : g_files) {
registerFile(file); registerFile(file);
} }
#ifdef EXTENSIONS
if (Extensions::TextureLoader::enabled) {
MxString directory =
MxString("/LEGO") + Extensions::TextureLoader::options["texture loader:texture path"].c_str();
Extensions::TextureLoader::options["texture loader:texture path"] = directory.GetData();
wasmfs_create_directory(directory.GetData(), 0644, fetchfs);
MxU32 i = 0;
Emscripten_SendExtensionProgress("HD Textures", 0);
for (const char* file : g_textures) {
MxString path = directory + "/" + file + ".bmp";
registerFile(path.GetData());
if (!preloadFile(path.GetData())) {
Extensions::TextureLoader::excludedFiles.emplace_back(file);
}
Emscripten_SendExtensionProgress("HD Textures", (++i * 100) / sizeOfArray(g_textures));
}
}
#endif
if (GameState()->GetSavePath() && *GameState()->GetSavePath() && !Emscripten_OPFSDisabled()) { if (GameState()->GetSavePath() && *GameState()->GetSavePath() && !Emscripten_OPFSDisabled()) {
if (!opfs) { if (!opfs) {
opfs = wasmfs_create_opfs_backend(); opfs = wasmfs_create_opfs_backend();

View File

@ -84,7 +84,8 @@ void Emscripten_ConvertEventToRenderCoordinates(SDL_Event* event)
} }
case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_MOTION:
case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_DOWN:
case SDL_EVENT_FINGER_UP: { case SDL_EVENT_FINGER_UP:
case SDL_EVENT_FINGER_CANCELED: {
const float scale = std::min(g_fullWidth / g_targetWidth, g_fullHeight / g_targetHeight); const float scale = std::min(g_fullWidth / g_targetWidth, g_fullHeight / g_targetHeight);
const float widthRatio = (g_targetWidth * scale) / g_fullWidth; const float widthRatio = (g_targetWidth * scale) / g_fullWidth;
const float heightRatio = (g_targetHeight * scale) / g_fullHeight; const float heightRatio = (g_targetHeight * scale) / g_fullHeight;

View File

@ -185,8 +185,13 @@ IsleApp::IsleApp()
m_haptic = TRUE; m_haptic = TRUE;
m_xRes = 640; m_xRes = 640;
m_yRes = 480; m_yRes = 480;
m_exclusiveXRes = m_xRes;
m_exclusiveYRes = m_yRes;
m_exclusiveFrameRate = 60.00f;
m_frameRate = 100.0f; m_frameRate = 100.0f;
m_exclusiveFullScreen = FALSE; m_exclusiveFullScreen = FALSE;
m_msaaSamples = 0;
m_anisotropic = 0.0f;
} }
// FUNCTION: ISLE 0x4011a0 // FUNCTION: ISLE 0x4011a0
@ -291,7 +296,7 @@ void IsleApp::SetupVideoFlags(
m_videoParam.Flags().SetLacksLightSupport(!hasLightSupport); m_videoParam.Flags().SetLacksLightSupport(!hasLightSupport);
m_videoParam.Flags().SetF1bit7(param_7); m_videoParam.Flags().SetF1bit7(param_7);
m_videoParam.Flags().SetWideViewAngle(wideViewAngle); m_videoParam.Flags().SetWideViewAngle(wideViewAngle);
m_videoParam.Flags().SetF2bit1(1); m_videoParam.Flags().SetEnabled(TRUE);
m_videoParam.SetDeviceName(deviceId); m_videoParam.SetDeviceName(deviceId);
if (using8bit) { if (using8bit) {
m_videoParam.Flags().Set16Bit(0); m_videoParam.Flags().Set16Bit(0);
@ -484,6 +489,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_MOTION:
case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_DOWN:
case SDL_EVENT_FINGER_UP: case SDL_EVENT_FINGER_UP:
case SDL_EVENT_FINGER_CANCELED:
IDirect3DRMMiniwinDevice* device = GetD3DRMMiniwinDevice(); IDirect3DRMMiniwinDevice* device = GetD3DRMMiniwinDevice();
if (device && !device->ConvertEventToRenderCoordinates(event)) { if (device && !device->ConvertEventToRenderCoordinates(event)) {
SDL_Log("Failed to convert event coordinates: %s", SDL_GetError()); SDL_Log("Failed to convert event coordinates: %s", SDL_GetError());
@ -512,6 +518,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
} }
break; break;
case SDL_EVENT_WINDOW_CLOSE_REQUESTED: case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
case SDL_EVENT_QUIT:
if (!g_closed) { if (!g_closed) {
delete g_isle; delete g_isle;
g_isle = NULL; g_isle = NULL;
@ -777,7 +784,8 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
); );
} }
break; break;
case SDL_EVENT_FINGER_UP: { case SDL_EVENT_FINGER_UP:
case SDL_EVENT_FINGER_CANCELED: {
g_mousedown = FALSE; g_mousedown = FALSE;
float x = SDL_clamp(event->tfinger.x, 0, 1) * g_targetWidth; float x = SDL_clamp(event->tfinger.x, 0, 1) * g_targetWidth;
@ -791,9 +799,6 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
} }
break; break;
} }
case SDL_EVENT_QUIT:
return SDL_APP_SUCCESS;
break;
} }
if (event->user.type == g_legoSdlEvents.m_windowsMessage) { if (event->user.type == g_legoSdlEvents.m_windowsMessage) {
@ -832,12 +837,31 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
SDL_Log("Game started"); SDL_Log("Game started");
} }
} }
else if (event->user.type == g_legoSdlEvents.m_hitActor && g_isle->GetHaptic()) { else if (event->user.type == g_legoSdlEvents.m_gameEvent) {
if (!InputManager()->HandleRumbleEvent(0.5f, 0.5f, 0.5f, 700)) { auto rumble = [](float p_strength, float p_lowFrequencyRumble, float p_highFrequencyRumble, MxU32 p_milliseconds
) {
if (g_isle->GetHaptic() &&
!InputManager()
->HandleRumbleEvent(p_strength, p_lowFrequencyRumble, p_highFrequencyRumble, p_milliseconds)) {
// Platform-specific handling // Platform-specific handling
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
Emscripten_HandleRumbleEvent(0.5f, 0.5f, 700); Emscripten_HandleRumbleEvent(p_lowFrequencyRumble, p_highFrequencyRumble, p_milliseconds);
#endif #endif
}
};
switch (event->user.code) {
case e_hitActor:
rumble(0.5f, 0.5f, 0.5f, 700);
break;
case e_skeletonKick:
rumble(0.8f, 0.8f, 0.8f, 2500);
break;
case e_raceFinished:
case e_goodEnding:
case e_badEnding:
rumble(1.0f, 1.0f, 1.0f, 3000);
break;
} }
} }
@ -916,11 +940,19 @@ MxResult IsleApp::SetupWindow()
#endif #endif
window = SDL_CreateWindowWithProperties(props); window = SDL_CreateWindowWithProperties(props);
SDL_SetPointerProperty(SDL_GetWindowProperties(window), ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM, &m_videoParam);
if (m_exclusiveFullScreen && m_fullScreen) { if (m_exclusiveFullScreen && m_fullScreen) {
SDL_DisplayMode closestMode; SDL_DisplayMode closestMode;
SDL_DisplayID displayID = SDL_GetDisplayForWindow(window); SDL_DisplayID displayID = SDL_GetDisplayForWindow(window);
if (SDL_GetClosestFullscreenDisplayMode(displayID, m_xRes, m_yRes, m_frameRate, true, &closestMode)) { if (SDL_GetClosestFullscreenDisplayMode(
displayID,
m_exclusiveXRes,
m_exclusiveYRes,
m_exclusiveFrameRate,
true,
&closestMode
)) {
SDL_SetWindowFullscreenMode(window, &closestMode); SDL_SetWindowFullscreenMode(window, &closestMode);
} }
} }
@ -1098,6 +1130,9 @@ bool IsleApp::LoadConfig()
iniparser_set(dict, "isle:Haptic", m_haptic ? "true" : "false"); iniparser_set(dict, "isle:Haptic", m_haptic ? "true" : "false");
iniparser_set(dict, "isle:Horizontal Resolution", SDL_itoa(m_xRes, buf, 10)); iniparser_set(dict, "isle:Horizontal Resolution", SDL_itoa(m_xRes, buf, 10));
iniparser_set(dict, "isle:Vertical Resolution", SDL_itoa(m_yRes, buf, 10)); iniparser_set(dict, "isle:Vertical Resolution", SDL_itoa(m_yRes, buf, 10));
iniparser_set(dict, "isle:Exclusive X Resolution", SDL_itoa(m_exclusiveXRes, buf, 10));
iniparser_set(dict, "isle:Exclusive Y Resolution", SDL_itoa(m_exclusiveYRes, buf, 10));
iniparser_set(dict, "isle:Exclusive Framerate", SDL_itoa(m_exclusiveFrameRate, buf, 10));
iniparser_set(dict, "isle:Frame Delta", SDL_itoa(m_frameDelta, buf, 10)); iniparser_set(dict, "isle:Frame Delta", SDL_itoa(m_frameDelta, buf, 10));
#ifdef EXTENSIONS #ifdef EXTENSIONS
@ -1175,11 +1210,16 @@ bool IsleApp::LoadConfig()
m_haptic = iniparser_getboolean(dict, "isle:Haptic", m_haptic); m_haptic = iniparser_getboolean(dict, "isle:Haptic", m_haptic);
m_xRes = iniparser_getint(dict, "isle:Horizontal Resolution", m_xRes); m_xRes = iniparser_getint(dict, "isle:Horizontal Resolution", m_xRes);
m_yRes = iniparser_getint(dict, "isle:Vertical Resolution", m_yRes); m_yRes = iniparser_getint(dict, "isle:Vertical Resolution", m_yRes);
m_exclusiveXRes = iniparser_getint(dict, "isle:Exclusive X Resolution", m_exclusiveXRes);
m_exclusiveYRes = iniparser_getint(dict, "isle:Exclusive Y Resolution", m_exclusiveXRes);
m_exclusiveFrameRate = iniparser_getdouble(dict, "isle:Exclusive Framerate", m_exclusiveFrameRate);
if (!m_fullScreen) { if (!m_fullScreen) {
m_videoParam.GetRect() = MxRect32(0, 0, (m_xRes - 1), (m_yRes - 1)); m_videoParam.GetRect() = MxRect32(0, 0, (m_xRes - 1), (m_yRes - 1));
} }
m_frameRate = (1000.0f / iniparser_getdouble(dict, "isle:Frame Delta", m_frameDelta)); m_frameRate = (1000.0f / iniparser_getdouble(dict, "isle:Frame Delta", m_frameDelta));
m_frameDelta = static_cast<int>(std::round(iniparser_getdouble(dict, "isle:Frame Delta", m_frameDelta))); m_frameDelta = static_cast<int>(std::round(iniparser_getdouble(dict, "isle:Frame Delta", m_frameDelta)));
m_videoParam.SetMSAASamples((m_msaaSamples = iniparser_getint(dict, "isle:MSAA", m_msaaSamples)));
m_videoParam.SetAnisotropic((m_anisotropic = iniparser_getdouble(dict, "isle:Anisotropic", m_anisotropic)));
const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL); const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL);
if (deviceId != NULL) { if (deviceId != NULL) {

View File

@ -109,8 +109,13 @@ class IsleApp {
MxBool m_haptic; MxBool m_haptic;
MxS32 m_xRes; MxS32 m_xRes;
MxS32 m_yRes; MxS32 m_yRes;
MxS32 m_exclusiveXRes;
MxS32 m_exclusiveYRes;
MxFloat m_exclusiveFrameRate;
MxFloat m_frameRate; MxFloat m_frameRate;
MxBool m_exclusiveFullScreen; MxBool m_exclusiveFullScreen;
MxU32 m_msaaSamples;
MxFloat m_anisotropic;
}; };
extern IsleApp* g_isle; extern IsleApp* g_isle;

View File

@ -46,7 +46,7 @@ class DebugViewer {
if (plantManager->m_numEntries) { if (plantManager->m_numEntries) {
if (ImGui::BeginTable("Animated Entries", 4, ImGuiTableFlags_Borders)) { if (ImGui::BeginTable("Animated Entries", 4, ImGuiTableFlags_Borders)) {
ImGui::TableSetupColumn("ROI Name"); ImGui::TableSetupColumn("ROI Name");
ImGui::TableSetupColumn("ROI m_unk0x100"); ImGui::TableSetupColumn("ROI m_sharedLodList");
ImGui::TableSetupColumn("Entity Name"); ImGui::TableSetupColumn("Entity Name");
ImGui::TableSetupColumn("Time"); ImGui::TableSetupColumn("Time");
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
@ -55,7 +55,7 @@ class DebugViewer {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::Text("%s", entry->m_roi->m_name); ImGui::Text("%s", entry->m_roi->m_name);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%d", entry->m_roi->m_unk0x100); ImGui::Text("%d", entry->m_roi->m_sharedLodList);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%s", entry->m_roi->m_entity->ClassName()); ImGui::Text("%s", entry->m_roi->m_entity->ClassName());
ImGui::TableNextColumn(); ImGui::TableNextColumn();
@ -75,7 +75,7 @@ class DebugViewer {
if (buildingManager->m_numEntries) { if (buildingManager->m_numEntries) {
if (ImGui::BeginTable("Animated Entries", 6, ImGuiTableFlags_Borders)) { if (ImGui::BeginTable("Animated Entries", 6, ImGuiTableFlags_Borders)) {
ImGui::TableSetupColumn("ROI Name"); ImGui::TableSetupColumn("ROI Name");
ImGui::TableSetupColumn("ROI m_unk0x100"); ImGui::TableSetupColumn("ROI m_sharedLodList");
ImGui::TableSetupColumn("Entity Name"); ImGui::TableSetupColumn("Entity Name");
ImGui::TableSetupColumn("Time"); ImGui::TableSetupColumn("Time");
ImGui::TableSetupColumn("Y"); ImGui::TableSetupColumn("Y");
@ -86,13 +86,13 @@ class DebugViewer {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::Text("%s", entry->m_roi->m_name); ImGui::Text("%s", entry->m_roi->m_name);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%d", entry->m_roi->m_unk0x100); ImGui::Text("%d", entry->m_roi->m_sharedLodList);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%s", entry->m_roi->m_entity->ClassName()); ImGui::Text("%s", entry->m_roi->m_entity->ClassName());
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%d", entry->m_time); ImGui::Text("%d", entry->m_time);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%d", entry->m_y); ImGui::Text("%f", entry->m_y);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%d", entry->m_muted); ImGui::Text("%d", entry->m_muted);
} }
@ -135,7 +135,7 @@ class DebugViewer {
ImGui::Text("unk0x70: %u", videoManager->m_unk0x70); ImGui::Text("unk0x70: %u", videoManager->m_unk0x70);
ImGui::Text("Dither: %d", videoManager->m_dither); ImGui::Text("Dither: %d", videoManager->m_dither);
ImGui::Text("BufferCount: %u", videoManager->m_bufferCount); ImGui::Text("BufferCount: %u", videoManager->m_bufferCount);
ImGui::Text("Paused: %f", videoManager->m_paused); ImGui::Text("Paused: %d", videoManager->m_paused);
ImGui::Text("back: %g", videoManager->m_back); ImGui::Text("back: %g", videoManager->m_back);
ImGui::Text("front: %g", videoManager->m_front); ImGui::Text("front: %g", videoManager->m_front);
ImGui::Text("cameraWidth: %g", videoManager->m_cameraWidth); ImGui::Text("cameraWidth: %g", videoManager->m_cameraWidth);

View File

@ -46,3 +46,24 @@ const char* g_files[46] = {
"/LEGO/data/WORLD.WDB", "/LEGO/data/WORLD.WDB",
"/LEGO/data/testinf.dta", "/LEGO/data/testinf.dta",
}; };
const char* g_textures[120] = {
"bank01.gif", "beach.gif", "black.gif", "bowtie.gif", "brela_01.gif", "bth1chst.gif", "bth2chst.gif",
"capch.gif", "capdb.gif", "capjs.gif", "capmd.gif", "caprc.gif", "cave_24x.gif", "caverocx.gif",
"caverokx.gif", "cheker01.gif", "construct.gif", "copchest.gif", "dbfrfn.gif", "doctor.gif", "dogface.gif",
"dummy.gif", "e.gif", "flowers.gif", "fruit.gif", "gasroad.gif", "gdface.gif", "g.gif",
"grassx.gif", "infochst.gif", "infoface.gif", "jailpad.gif", "jfrnt.gif", "jsfrnt4.gif", "jsfrnt.gif",
"jside.gif", "jswnsh5.gif", "jswnsh.gif", "l6.gif", "l.gif", "mamachst.gif", "mamaface.gif",
"mamamap.gif", "mech.gif", "medic01.gif", "mitesx.gif", "mustache.gif", "nickchst.gif", "nickface.gif",
"nickmap.gif", "nopizza.gif", "norachst.gif", "noraface.gif", "noramap.gif", "nwcurve.gif", "octan01.gif",
"octsq01.gif", "o.gif", "papachst.gif", "papaface.gif", "papamap.gif", "pebblesx.gif", "pepperha.gif",
"peppizza.gif", "peppmap.gif", "peprchst.gif", "peprface.gif", "pianokys.gif", "pizcurve.gif", "pizza01.gif",
"pizza.gif", "polbar01.gif", "polbla01.gif", "polkadot.gif", "polwhi01.gif", "postchst.gif", "post.gif",
"rac1chst.gif", "rac2chst.gif", "radar.gif", "raddis01.gif", "rcback.gif", "rc-butn.gif", "rcfrnt5.gif",
"rcfrnt6.gif", "rcfrnt7.gif", "rcfrnt.gif", "rcside1.gif", "rcside2.gif", "rcside3.gif", "rctail.gif",
"redskul.gif", "relrel01.gif", "road1way.gif", "road3wa2.gif", "road3wa3.gif", "road3way.gif", "road4way.gif",
"roadstr8.gif", "rockx.gif", "roofpiz.gif", "sandredx.gif", "se_curve.gif", "shftchst.gif", "shftface2.gif",
"shftface.gif", "shldwn02.gif", "skull.gif", "smile.gif", "smileshd.gif", "supr2_01.gif", "tightcrv.gif",
"unkchst.gif", "val_02.gif", "vest.gif", "water2x.gif", "w_curve.gif", "wnbars.gif", "woman.gif",
"womanshd.gif"
};

View File

@ -211,7 +211,7 @@ class Ambulance : public IslePathActor {
MxS16 m_atPoliceTask; // 0x16c MxS16 m_atPoliceTask; // 0x16c
MxS16 m_atBeachTask; // 0x16e MxS16 m_atBeachTask; // 0x16e
MxS16 m_taskState; // 0x170 MxS16 m_taskState; // 0x170
MxS16 m_unk0x172; // 0x172 MxS16 m_enableRandomAudio; // 0x172
IsleScript::Script m_lastAction; // 0x174 IsleScript::Script m_lastAction; // 0x174
IsleScript::Script m_lastAnimation; // 0x178 IsleScript::Script m_lastAnimation; // 0x178
MxFloat m_fuel; // 0x17c MxFloat m_fuel; // 0x17c

View File

@ -18,6 +18,25 @@ class LegoControlManagerNotificationParam;
// SIZE 0x94 // SIZE 0x94
class InfocenterState : public LegoState { class InfocenterState : public LegoState {
public: public:
enum {
e_playCutscene = 0,
e_introCancelled = 1,
e_notRegistered = 2,
e_newState = 3,
e_selectedSave = 4,
e_selectedCharacterAndDestination = 5,
// e_6 = 6,
// e_7 = 7,
e_exitQueried = 8,
// e_9 = 9,
// e_10 = 10,
e_welcomeAnimation = 11,
e_exiting = 12,
e_playCredits = 13,
e_exitingToIsland = 14,
e_backToInfoAct1 = 15,
};
InfocenterState(); InfocenterState();
~InfocenterState() override; ~InfocenterState() override;
@ -72,7 +91,7 @@ class InfocenterState : public LegoState {
Playlist m_returnDialogue[3]; // 0x20 Playlist m_returnDialogue[3]; // 0x20
Playlist m_leaveDialogue[3]; // 0x44 Playlist m_leaveDialogue[3]; // 0x44
Playlist m_bricksterDialogue; // 0x68 Playlist m_bricksterDialogue; // 0x68
MxU32 m_unk0x74; // 0x74 MxU32 m_state; // 0x74
MxStillPresenter* m_letters[7]; // 0x78 MxStillPresenter* m_letters[7]; // 0x78
}; };

View File

@ -150,18 +150,18 @@ class Isle : public LegoWorld {
return !strcmp(p_name, Isle::ClassName()) || LegoWorld::IsA(p_name); return !strcmp(p_name, Isle::ClassName()) || LegoWorld::IsA(p_name);
} }
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
void ReadyWorld() override; // vtable+0x50 void ReadyWorld() override; // vtable+0x50
void Add(MxCore* p_object) override; // vtable+0x58 void Add(MxCore* p_object) override; // vtable+0x58
void VTable0x60() override; // vtable+0x60 void VTable0x60() override; // vtable+0x60
MxBool Escape() override; // vtable+0x64 MxBool Escape() override; // vtable+0x64
void Enable(MxBool p_enable) override; // vtable+0x68 void Enable(MxBool p_enable) override; // vtable+0x68
virtual void VTable0x6c(LegoPathActor* p_actor); // vtable+0x6c virtual void RemoveVehicle(LegoPathActor* p_actor); // vtable+0x6c
void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; } void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; }
MxBool HasHelicopter() { return m_helicopter != NULL; } MxBool HasHelicopter() { return m_helicopter != NULL; }
void FUN_10033350(); void SwitchToInfocenter();
friend class Act1State; friend class Act1State;
@ -175,13 +175,13 @@ class Isle : public LegoWorld {
MxLong HandleTransitionEnd(); MxLong HandleTransitionEnd();
void HandleElevatorEndAction(); void HandleElevatorEndAction();
void UpdateGlobe(); void UpdateGlobe();
void FUN_10032620(); void CheckAreaExiting();
void CreateState(); void CreateState();
void FUN_10032d30( void TransitionToOverlay(
IsleScript::Script p_script, IsleScript::Script p_script,
JukeboxScript::Script p_music, JukeboxScript::Script p_music,
const char* p_cameraLocation, const char* p_cameraLocation,
MxBool p_und MxBool p_setCamera
); );
Act1State* m_act1state; // 0xf8 Act1State* m_act1state; // 0xf8

View File

@ -35,7 +35,7 @@ class Jetski : public IslePathActor {
void ActivateSceneActions(); void ActivateSceneActions();
MxS16 GetUnknown0x160() { return m_jetskiDashboardStreamId; } MxS16 GetJetskiDashboardStreamId() { return m_jetskiDashboardStreamId; }
// SYNTHETIC: LEGO1 0x1007e5c0 // SYNTHETIC: LEGO1 0x1007e5c0
// Jetski::`scalar deleting destructor' // Jetski::`scalar deleting destructor'

View File

@ -304,4 +304,7 @@ class LegoAnimationManager : public MxCore {
// TEMPLATE: LEGO1 0x10061750 // TEMPLATE: LEGO1 0x10061750
// MxListCursor<LegoTranInfo *>::MxListCursor<LegoTranInfo *> // MxListCursor<LegoTranInfo *>::MxListCursor<LegoTranInfo *>
// TEMPLATE: BETA10 0x1004b5d0
// MxListCursor<LegoTranInfo *>::Next
#endif // LEGOANIMATIONMANAGER_H #endif // LEGOANIMATIONMANAGER_H

View File

@ -2,6 +2,7 @@
#define LEGOANIMPRESENTER_H #define LEGOANIMPRESENTER_H
#include "legoroilist.h" #include "legoroilist.h"
#include "legoroimaplist.h"
#include "mxatom.h" #include "mxatom.h"
#include "mxvideopresenter.h" #include "mxvideopresenter.h"
@ -147,14 +148,191 @@ class LegoAnimPresenter : public MxVideoPresenter {
MxS16 m_unk0x9c; // 0x9c MxS16 m_unk0x9c; // 0x9c
Matrix4* m_unk0xa0; // 0xa0 Matrix4* m_unk0xa0; // 0xa0
// SYNTHETIC: LEGO1 0x10068650
// LegoAnimPresenter::`scalar deleting destructor'
public: public:
float m_unk0xa4; // 0xa4 float m_unk0xa4; // 0xa4
Mx3DPointFloat m_unk0xa8; // 0xa8 Mx3DPointFloat m_unk0xa8; // 0xa8
}; };
// VTABLE: LEGO1 0x100d4900
// SIZE 0xc0
class LegoLoopingAnimPresenter : public LegoAnimPresenter {
public:
// FUNCTION: BETA10 0x1005c6f0
static const char* HandlerClassName()
{
// STRING: LEGO1 0x100f0700
return "LegoLoopingAnimPresenter";
}
// FUNCTION: LEGO1 0x1000c9a0
// FUNCTION: BETA10 0x1005c6c0
const char* ClassName() const override // vtable+0x0c
{
return HandlerClassName();
}
// FUNCTION: LEGO1 0x1000c9b0
MxBool IsA(const char* p_name) const override // vtable+0x10
{
return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name);
}
void StreamingTickle() override; // vtable+0x20
void PutFrame() override; // vtable+0x6c
// SYNTHETIC: LEGO1 0x1006d000
// LegoLoopingAnimPresenter::~LegoLoopingAnimPresenter
// SYNTHETIC: LEGO1 0x1000f440
// LegoLoopingAnimPresenter::`scalar deleting destructor'
private:
undefined4 m_unk0xbc; // 0xbc
};
class LegoAnimActor;
// VTABLE: LEGO1 0x100d9170
// SIZE 0xd8
class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter {
public:
LegoLocomotionAnimPresenter();
~LegoLocomotionAnimPresenter() override;
// FUNCTION: BETA10 0x1005c4e0
static const char* HandlerClassName()
{
// STRING: LEGO1 0x100f06e4
return "LegoLocomotionAnimPresenter";
}
// FUNCTION: LEGO1 0x1006ce50
// FUNCTION: BETA10 0x1005c4b0
const char* ClassName() const override // vtable+0x0c
{
return HandlerClassName();
}
// FUNCTION: LEGO1 0x1006ce60
MxBool IsA(const char* p_name) const override // vtable+0x10
{
return !strcmp(p_name, ClassName()) || LegoLoopingAnimPresenter::IsA(p_name);
}
void ReadyTickle() override; // vtable+0x18
void StartingTickle() override; // vtable+0x1c
void StreamingTickle() override; // vtable+0x20
MxResult AddToManager() override; // vtable+0x34
void Destroy() override; // vtable+0x38
void EndAction() override; // vtable+0x40
void PutFrame() override; // vtable+0x6c
MxResult CreateAnim(MxStreamChunk* p_chunk) override; // vtable+0x88
void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value);
void DecrementUnknown0xd4()
{
if (m_unk0xd4) {
--m_unk0xd4;
}
}
undefined2 GetUnknown0xd4() { return m_unk0xd4; }
// SYNTHETIC: LEGO1 0x1006cfe0
// LegoLocomotionAnimPresenter::`scalar deleting destructor'
private:
void Init();
void Destroy(MxBool p_fromDestructor);
undefined4 m_unk0xc0; // 0xc0
undefined4* m_unk0xc4; // 0xc4
LegoROIMapList* m_roiMapList; // 0xc8
MxS32 m_unk0xcc; // 0xcc
MxS32 m_unk0xd0; // 0xd0
undefined2 m_unk0xd4; // 0xd4
};
class LegoPathBoundary;
struct LegoHideAnimStructComparator {
MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; }
};
// SIZE 0x08
struct LegoHideAnimStruct {
LegoPathBoundary* m_boundary; // 0x00
MxU32 m_index; // 0x04
};
typedef map<const char*, LegoHideAnimStruct, LegoHideAnimStructComparator> LegoHideAnimStructMap;
// VTABLE: LEGO1 0x100d9278
// SIZE 0xc4
class LegoHideAnimPresenter : public LegoLoopingAnimPresenter {
public:
LegoHideAnimPresenter();
~LegoHideAnimPresenter() override;
// FUNCTION: LEGO1 0x1006d860
void VTable0x8c() override {} // vtable+0x8c
// FUNCTION: LEGO1 0x1006d870
void VTable0x90() override {} // vtable+0x90
// FUNCTION: BETA10 0x1005d4a0
static const char* HandlerClassName()
{
// STRING: LEGO1 0x100f06cc
return "LegoHideAnimPresenter";
}
// FUNCTION: LEGO1 0x1006d880
// FUNCTION: BETA10 0x1005d470
const char* ClassName() const override // vtable+0x0c
{
return HandlerClassName();
}
// FUNCTION: LEGO1 0x1006d890
MxBool IsA(const char* p_name) const override // vtable+0x10
{
return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name);
}
void ReadyTickle() override; // vtable+0x18
void StartingTickle() override; // vtable+0x18
MxResult AddToManager() override; // vtable+0x34
void Destroy() override; // vtable+0x38
void EndAction() override; // vtable+0x40
void PutFrame() override; // vtable+0x6c
void FUN_1006db40(LegoTime p_time);
// SYNTHETIC: LEGO1 0x1006d9d0
// LegoHideAnimPresenter::`scalar deleting destructor'
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(
LegoHideAnimStructMap& p_map,
LegoAnimNodeData* p_data,
const char* p_name,
LegoPathBoundary* p_boundary
);
LegoPathBoundary** m_boundaryMap; // 0xc0
};
// clang-format off // clang-format off
// SYNTHETIC: LEGO1 0x10068650
// LegoAnimPresenter::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100689c0 // TEMPLATE: LEGO1 0x100689c0
// map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::~map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> > // map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::~map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >
@ -212,6 +390,33 @@ class LegoAnimPresenter : public MxVideoPresenter {
// GLOBAL: LEGO1 0x100f7688 // GLOBAL: LEGO1 0x100f7688
// _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Nil // _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Nil
// TEMPLATE: LEGO1 0x1006ddb0
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::~_Tree<char const *,pair<ch
// TEMPLATE: LEGO1 0x1006de80
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::iterator::_Inc
// TEMPLATE: LEGO1 0x1006dec0
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::erase
// TEMPLATE: LEGO1 0x1006e310
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Erase
// TEMPLATE: LEGO1 0x1006e350
// Map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator>::~Map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator>
// TEMPLATE: LEGO1 0x1006e3a0
// map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::~map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >
// TEMPLATE: LEGO1 0x1006e6d0
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::iterator::_Dec
// TEMPLATE: LEGO1 0x1006e720
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Insert
// GLOBAL: LEGO1 0x100f768c
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Nil
// clang-format on // clang-format on
#endif // LEGOANIMPRESENTER_H #endif // LEGOANIMPRESENTER_H

View File

@ -59,7 +59,8 @@ class LegoBuildingManager : public MxCore {
// FUNCTION: LEGO1 0x1002f930 // FUNCTION: LEGO1 0x1002f930
const char* ClassName() const override // vtable+0x0c const char* ClassName() const override // vtable+0x0c
{ {
// not in BETA10 // While this class exists in BETA10, it didn't have a ClassName().
// The constructor suggests that it did not inherit from MxCore back then and did not have a VTABLE.
// STRING: LEGO1 0x100f37d0 // STRING: LEGO1 0x100f37d0
return "LegoBuildingManager"; return "LegoBuildingManager";
} }

View File

@ -48,10 +48,13 @@ typedef set<LegoCacheSoundEntry, Set100d6b4cComparator> Set100d6b4c;
typedef list<LegoCacheSoundEntry> List100d6b4c; typedef list<LegoCacheSoundEntry> List100d6b4c;
// VTABLE: LEGO1 0x100d6b4c // VTABLE: LEGO1 0x100d6b4c
// VTABLE: BETA10 0x101becac
// SIZE 0x20 // SIZE 0x20
class LegoCacheSoundManager { class LegoCacheSoundManager {
public: public:
// FUNCTION: BETA10 0x100d0a60
LegoCacheSoundManager() {} LegoCacheSoundManager() {}
~LegoCacheSoundManager(); ~LegoCacheSoundManager();
virtual MxResult Tickle(); // vtable+0x00 virtual MxResult Tickle(); // vtable+0x00
@ -68,6 +71,9 @@ class LegoCacheSoundManager {
List100d6b4c m_list; // 0x14 List100d6b4c m_list; // 0x14
}; };
// SYNTHETIC: BETA10 0x100d06b0
// LegoCacheSoundManager::`scalar deleting destructor'
// TODO: Function names subject to change. // TODO: Function names subject to change.
// clang-format off // clang-format off

View File

@ -38,17 +38,17 @@ class LegoCameraController : public LegoPointOfViewController {
virtual MxResult Create(); // vtable+0x44 virtual MxResult Create(); // vtable+0x44
void SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up); void SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up);
void FUN_10012290(float p_angle); void RotateZ(float p_angle);
void FUN_10012320(float p_angle); void RotateY(float p_angle);
MxResult FUN_100123b0(Matrix4& p_matrix); MxResult GetPointOfView(Matrix4& p_matrix);
void FUN_100123e0(const Matrix4& p_transform, MxU32 p_und); void TransformPointOfView(const Matrix4& p_transform, MxU32 p_multiply);
Mx3DPointFloat GetWorldUp(); Mx3DPointFloat GetWorldUp();
Mx3DPointFloat GetWorldLocation(); Mx3DPointFloat GetWorldLocation();
Mx3DPointFloat GetWorldDirection(); Mx3DPointFloat GetWorldDirection();
private: private:
MxMatrix m_matrix1; // 0x38 MxMatrix m_currentTransform; // 0x38
MxMatrix m_matrix2; // 0x80 MxMatrix m_originalTransform; // 0x80
}; };
// SYNTHETIC: LEGO1 0x10011f50 // SYNTHETIC: LEGO1 0x10011f50

View File

@ -48,6 +48,7 @@ struct LegoActorInfo;
typedef map<char*, LegoCharacter*, LegoCharacterComparator> LegoCharacterMap; typedef map<char*, LegoCharacter*, LegoCharacterComparator> LegoCharacterMap;
// VTABLE: LEGO1 0x100da878 // VTABLE: LEGO1 0x100da878
// VTABLE: BETA10 0x101bc028
// SIZE 0x24 // SIZE 0x24
class CustomizeAnimFileVariable : public MxVariable { class CustomizeAnimFileVariable : public MxVariable {
public: public:

View File

@ -24,11 +24,11 @@ class LegoControlManagerNotificationParam : public LegoEventNotificationParam {
void SetClickedObjectId(MxS32 p_clickedObjectId) { m_clickedObjectId = p_clickedObjectId; } void SetClickedObjectId(MxS32 p_clickedObjectId) { m_clickedObjectId = p_clickedObjectId; }
void SetClickedAtom(const char* p_clickedAtom) { m_clickedAtom = p_clickedAtom; } void SetClickedAtom(const char* p_clickedAtom) { m_clickedAtom = p_clickedAtom; }
void SetUnknown0x28(MxS16 p_unk0x28) { m_unk0x28 = p_unk0x28; } void SetEnabledChild(MxS16 p_enabledChild) { m_enabledChild = p_enabledChild; }
MxS32 m_clickedObjectId; // 0x20 MxS32 m_clickedObjectId; // 0x20
const char* m_clickedAtom; // 0x24 const char* m_clickedAtom; // 0x24
MxS16 m_unk0x28; // 0x28 MxS16 m_enabledChild; // 0x28
}; };
// SYNTHETIC: LEGO1 0x10028bf0 // SYNTHETIC: LEGO1 0x10028bf0

View File

@ -30,6 +30,7 @@ struct InternationalCharacter {
}; };
// VTABLE: LEGO1 0x100d74a8 // VTABLE: LEGO1 0x100d74a8
// VTABLE: BETA10 0x101bc4f0
// SIZE 0x30 // SIZE 0x30
class LegoBackgroundColor : public MxVariable { class LegoBackgroundColor : public MxVariable {
public: public:
@ -50,9 +51,11 @@ class LegoBackgroundColor : public MxVariable {
}; };
// VTABLE: LEGO1 0x100d74b8 // VTABLE: LEGO1 0x100d74b8
// VTABLE: BETA10 0x101bc500
// SIZE 0x24 // SIZE 0x24
class LegoFullScreenMovie : public MxVariable { class LegoFullScreenMovie : public MxVariable {
public: public:
LegoFullScreenMovie();
LegoFullScreenMovie(const char* p_key, const char* p_value); LegoFullScreenMovie(const char* p_key, const char* p_value);
void SetValue(const char* p_option) override; // vtable+0x04 void SetValue(const char* p_option) override; // vtable+0x04
@ -110,19 +113,19 @@ class LegoGameState {
e_dunecarbuild, e_dunecarbuild,
e_jetskibuild, e_jetskibuild,
e_racecarbuild, e_racecarbuild,
e_unk40, e_helicopterSpawn,
e_unk41, e_unk41,
e_unk42, e_unk42,
e_unk43, e_dunebuggySpawn,
e_unk44, e_racecarSpawn,
e_unk45, e_jetskiSpawn,
e_act2main, e_act2main,
e_act3script, e_act3script,
e_unk48, e_unk48,
e_unk49, e_unk49,
e_unk50, e_unk50,
e_unk51, e_unk51,
e_unk52, e_towTrackHookedUp,
e_jukeboxw, e_jukeboxw,
e_jukeboxExterior, e_jukeboxExterior,
e_unk55, e_unk55,

View File

@ -1,111 +0,0 @@
#ifndef LEGOHIDEANIMPRESENTER_H
#define LEGOHIDEANIMPRESENTER_H
#include "decomp.h"
#include "legoloopinganimpresenter.h"
class LegoPathBoundary;
struct LegoHideAnimStructComparator {
MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; }
};
// SIZE 0x08
struct LegoHideAnimStruct {
LegoPathBoundary* m_boundary; // 0x00
MxU32 m_index; // 0x04
};
typedef map<const char*, LegoHideAnimStruct, LegoHideAnimStructComparator> LegoHideAnimStructMap;
// VTABLE: LEGO1 0x100d9278
// SIZE 0xc4
class LegoHideAnimPresenter : public LegoLoopingAnimPresenter {
public:
LegoHideAnimPresenter();
~LegoHideAnimPresenter() override;
// FUNCTION: LEGO1 0x1006d860
void VTable0x8c() override {} // vtable+0x8c
// FUNCTION: LEGO1 0x1006d870
void VTable0x90() override {} // vtable+0x90
// FUNCTION: BETA10 0x1005d4a0
static const char* HandlerClassName()
{
// STRING: LEGO1 0x100f06cc
return "LegoHideAnimPresenter";
}
// FUNCTION: LEGO1 0x1006d880
// FUNCTION: BETA10 0x1005d470
const char* ClassName() const override // vtable+0x0c
{
return HandlerClassName();
}
// FUNCTION: LEGO1 0x1006d890
MxBool IsA(const char* p_name) const override // vtable+0x10
{
return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name);
}
void ReadyTickle() override; // vtable+0x18
void StartingTickle() override; // vtable+0x18
MxResult AddToManager() override; // vtable+0x34
void Destroy() override; // vtable+0x38
void EndAction() override; // vtable+0x40
void PutFrame() override; // vtable+0x6c
void FUN_1006db40(LegoTime p_time);
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(
LegoHideAnimStructMap& p_map,
LegoAnimNodeData* p_data,
const char* p_name,
LegoPathBoundary* p_boundary
);
LegoPathBoundary** m_boundaryMap; // 0xc0
};
// clang-format off
// SYNTHETIC: LEGO1 0x1006d9d0
// LegoHideAnimPresenter::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1006ddb0
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::~_Tree<char const *,pair<ch
// TEMPLATE: LEGO1 0x1006de80
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::iterator::_Inc
// TEMPLATE: LEGO1 0x1006dec0
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::erase
// TEMPLATE: LEGO1 0x1006e310
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Erase
// TEMPLATE: LEGO1 0x1006e350
// Map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator>::~Map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator>
// TEMPLATE: LEGO1 0x1006e3a0
// map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::~map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >
// TEMPLATE: LEGO1 0x1006e6d0
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::iterator::_Dec
// TEMPLATE: LEGO1 0x1006e720
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Insert
// GLOBAL: LEGO1 0x100f768c
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Nil
// clang-format on
#endif // LEGOHIDEANIMPRESENTER_H

View File

@ -1,71 +0,0 @@
#ifndef LEGOLOCOMOTIONANIMPRESENTER_H
#define LEGOLOCOMOTIONANIMPRESENTER_H
#include "legoloopinganimpresenter.h"
#include "legoroimaplist.h"
class LegoAnimActor;
// VTABLE: LEGO1 0x100d9170
// SIZE 0xd8
class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter {
public:
LegoLocomotionAnimPresenter();
~LegoLocomotionAnimPresenter() override;
// FUNCTION: BETA10 0x1005c4e0
static const char* HandlerClassName()
{
// STRING: LEGO1 0x100f06e4
return "LegoLocomotionAnimPresenter";
}
// FUNCTION: LEGO1 0x1006ce50
// FUNCTION: BETA10 0x1005c4b0
const char* ClassName() const override // vtable+0x0c
{
return HandlerClassName();
}
// FUNCTION: LEGO1 0x1006ce60
MxBool IsA(const char* p_name) const override // vtable+0x10
{
return !strcmp(p_name, ClassName()) || LegoLoopingAnimPresenter::IsA(p_name);
}
void ReadyTickle() override; // vtable+0x18
void StartingTickle() override; // vtable+0x1c
void StreamingTickle() override; // vtable+0x20
MxResult AddToManager() override; // vtable+0x34
void Destroy() override; // vtable+0x38
void EndAction() override; // vtable+0x40
void PutFrame() override; // vtable+0x6c
MxResult CreateAnim(MxStreamChunk* p_chunk) override; // vtable+0x88
// SYNTHETIC: LEGO1 0x1006cfe0
// LegoLocomotionAnimPresenter::`scalar deleting destructor'
void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value);
void DecrementUnknown0xd4()
{
if (m_unk0xd4) {
--m_unk0xd4;
}
}
undefined2 GetUnknown0xd4() { return m_unk0xd4; }
private:
void Init();
void Destroy(MxBool p_fromDestructor);
undefined4 m_unk0xc0; // 0xc0
undefined4* m_unk0xc4; // 0xc4
LegoROIMapList* m_roiMapList; // 0xc8
MxS32 m_unk0xcc; // 0xcc
MxS32 m_unk0xd0; // 0xd0
undefined2 m_unk0xd4; // 0xd4
};
#endif // LEGOLOCOMOTIONANIMPRESENTER_H

View File

@ -1,43 +0,0 @@
#ifndef LEGOLOOPINGANIMPRESENTER_H
#define LEGOLOOPINGANIMPRESENTER_H
#include "legoanimpresenter.h"
// VTABLE: LEGO1 0x100d4900
// SIZE 0xc0
class LegoLoopingAnimPresenter : public LegoAnimPresenter {
public:
// FUNCTION: BETA10 0x1005c6f0
static const char* HandlerClassName()
{
// STRING: LEGO1 0x100f0700
return "LegoLoopingAnimPresenter";
}
// FUNCTION: LEGO1 0x1000c9a0
// FUNCTION: BETA10 0x1005c6c0
const char* ClassName() const override // vtable+0x0c
{
return HandlerClassName();
}
// FUNCTION: LEGO1 0x1000c9b0
MxBool IsA(const char* p_name) const override // vtable+0x10
{
return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name);
}
void StreamingTickle() override; // vtable+0x20
void PutFrame() override; // vtable+0x6c
private:
undefined4 m_unk0xbc; // 0xbc
};
// SYNTHETIC: LEGO1 0x1006d000
// LegoLoopingAnimPresenter::~LegoLoopingAnimPresenter
// SYNTHETIC: LEGO1 0x1000f440
// LegoLoopingAnimPresenter::`scalar deleting destructor'
#endif // LEGOLOOPINGANIMPRESENTER_H

View File

@ -5,7 +5,7 @@
#include "lego1_export.h" #include "lego1_export.h"
#include "legoutils.h" #include "legoutils.h"
#include "mxdsaction.h" #include "mxdsaction.h"
#include "mxomni.h" #include "mxmain.h"
#include <SDL3/SDL_events.h> #include <SDL3/SDL_events.h>
#include <SDL3/SDL_timer.h> #include <SDL3/SDL_timer.h>
@ -114,6 +114,7 @@ class LegoOmni : public MxOmni {
} }
// FUNCTION: LEGO1 0x10058ab0 // FUNCTION: LEGO1 0x10058ab0
// FUNCTION: BETA10 0x1008f860
MxBool IsA(const char* p_name) const override // vtable+0x10 MxBool IsA(const char* p_name) const override // vtable+0x10
{ {
return !strcmp(p_name, LegoOmni::ClassName()) || MxOmni::IsA(p_name); return !strcmp(p_name, LegoOmni::ClassName()) || MxOmni::IsA(p_name);
@ -153,9 +154,14 @@ class LegoOmni : public MxOmni {
// FUNCTION: BETA10 0x1009e7a0 // FUNCTION: BETA10 0x1009e7a0
LegoInputManager* GetInputManager() { return m_inputManager; } LegoInputManager* GetInputManager() { return m_inputManager; }
// FUNCTION: BETA10 0x100e5400
LegoTextureContainer* GetTextureContainer() { return m_textureContainer; } LegoTextureContainer* GetTextureContainer() { return m_textureContainer; }
ViewLODListManager* GetViewLODListManager() { return m_viewLODListManager; } ViewLODListManager* GetViewLODListManager() { return m_viewLODListManager; }
// FUNCTION: BETA10 0x100969b0
LegoWorld* GetCurrentWorld() { return m_currentWorld; } LegoWorld* GetCurrentWorld() { return m_currentWorld; }
LegoNavController* GetNavController() { return m_navController; } LegoNavController* GetNavController() { return m_navController; }
LegoPathActor* GetUserActor() { return m_userActor; } LegoPathActor* GetUserActor() { return m_userActor; }
@ -185,8 +191,8 @@ class LegoOmni : public MxOmni {
// FUNCTION: BETA10 0x100d55c0 // FUNCTION: BETA10 0x100d55c0
void SetExit(MxBool p_exit) { m_exit = p_exit; } void SetExit(MxBool p_exit) { m_exit = p_exit; }
MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; } MxResult StartActionIfInitialized(MxDSAction& p_dsAction) { return m_initialized ? Start(&p_dsAction) : SUCCESS; }
void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; } void SetInitialized(MxBool p_unk0x13c) { m_initialized = p_unk0x13c; }
void CloseMainWindow() void CloseMainWindow()
{ {
@ -204,6 +210,7 @@ class LegoOmni : public MxOmni {
MxBool IsVersion10() { return m_version10; } MxBool IsVersion10() { return m_version10; }
// SYNTHETIC: LEGO1 0x10058b30 // SYNTHETIC: LEGO1 0x10058b30
// SYNTHETIC: BETA10 0x1008f8d0
// LegoOmni::`scalar deleting destructor' // LegoOmni::`scalar deleting destructor'
private: private:
@ -227,7 +234,7 @@ class LegoOmni : public MxOmni {
MxBool m_version10; MxBool m_version10;
public: public:
MxBool m_unk0x13c; // 0x13c MxBool m_initialized; // 0x13c
}; };
#endif // LEGOMAIN_H #endif // LEGOMAIN_H

View File

@ -4,6 +4,7 @@
#include "lego1_export.h" #include "lego1_export.h"
#include "legonamedpartlist.h" #include "legonamedpartlist.h"
#include "mxmediapresenter.h" #include "mxmediapresenter.h"
#include "viewmanager/viewlodlist.h"
// VTABLE: LEGO1 0x100d4df0 // VTABLE: LEGO1 0x100d4df0
// SIZE 0x54 // SIZE 0x54
@ -50,10 +51,21 @@ class LegoPartPresenter : public MxMediaPresenter {
MxResult Read(MxDSChunk& p_chunk); MxResult Read(MxDSChunk& p_chunk);
void Store(); void Store();
static void Release()
{
for (auto* lodList : g_lodLists) {
lodList->Release();
}
g_lodLists.clear();
}
private: private:
void Destroy(MxBool p_fromDestructor); void Destroy(MxBool p_fromDestructor);
LegoNamedPartList* m_parts; // 0x50 LegoNamedPartList* m_parts; // 0x50
static vector<ViewLODList*> g_lodLists;
}; };
#endif // LEGOPARTPRESENTER_H #endif // LEGOPARTPRESENTER_H

View File

@ -31,6 +31,7 @@ typedef set<LegoPathActor*, LegoPathActorSetCompare> LegoPathActorSet;
typedef set<LegoAnimPresenter*, LegoAnimPresenterSetCompare> LegoAnimPresenterSet; typedef set<LegoAnimPresenter*, LegoAnimPresenterSetCompare> LegoAnimPresenterSet;
// VTABLE: LEGO1 0x100d8618 // VTABLE: LEGO1 0x100d8618
// VTABLE: BETA10 0x101bdd58
// SIZE 0x74 // SIZE 0x74
class LegoPathBoundary : public LegoWEGEdge { class LegoPathBoundary : public LegoWEGEdge {
public: public:
@ -57,6 +58,7 @@ class LegoPathBoundary : public LegoWEGEdge {
LegoAnimPresenterSet& GetPresenters() { return m_presenters; } LegoAnimPresenterSet& GetPresenters() { return m_presenters; }
// SYNTHETIC: LEGO1 0x10047a80 // SYNTHETIC: LEGO1 0x10047a80
// SYNTHETIC: BETA10 0x100bd300
// LegoPathBoundary::`vector deleting destructor' // LegoPathBoundary::`vector deleting destructor'
private: private:

View File

@ -42,9 +42,9 @@ class LegoPhonemePresenter : public MxFlcPresenter {
MxS32 m_rectCount; // 0x68 MxS32 m_rectCount; // 0x68
LegoTextureInfo* m_textureInfo; // 0x6c LegoTextureInfo* m_textureInfo; // 0x6c
MxBool m_unk0x70; // 0x70 MxBool m_reusedPhoneme; // 0x70
MxString m_roiName; // 0x74 MxString m_roiName; // 0x74
MxBool m_unk0x84; // 0x84 MxBool m_isPartOfAnimMM; // 0x84
}; };
// TEMPLATE: LEGO1 0x1004eb20 // TEMPLATE: LEGO1 0x1004eb20

View File

@ -32,7 +32,7 @@ class LEGO1_EXPORT LegoPlantManager : public MxCore {
const char* ClassName() const override // vtable+0x0c const char* ClassName() const override // vtable+0x0c
{ {
// While this class exists in BETA10, it didn't have a ClassName(). // While this class exists in BETA10, it didn't have a ClassName().
// I suppose it did not inherit from MxCore back then and likely did not have a VTABLE. // The constructor suggests that it did not inherit from MxCore back then and did not have a VTABLE.
// STRING: LEGO1 0x100f318c // STRING: LEGO1 0x100f318c
return "LegoPlantManager"; return "LegoPlantManager";
} }

View File

@ -17,15 +17,15 @@ class LegoSoundManager : public MxSoundManager {
void Destroy() override; // vtable+0x18 void Destroy() override; // vtable+0x18
MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread) override; // vtable+0x30 MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread) override; // vtable+0x30
// SYNTHETIC: LEGO1 0x10029920
// SYNTHETIC: BETA10 0x100d0660
// LegoSoundManager::`scalar deleting destructor'
void UpdateListener(const float* p_position, const float* p_direction, const float* p_up, const float* p_velocity); void UpdateListener(const float* p_position, const float* p_direction, const float* p_up, const float* p_velocity);
// FUNCTION: BETA10 0x1000f350 // FUNCTION: BETA10 0x1000f350
LegoCacheSoundManager* GetCacheSoundManager() { return m_cacheSoundManager; } LegoCacheSoundManager* GetCacheSoundManager() { return m_cacheSoundManager; }
// SYNTHETIC: LEGO1 0x10029920
// SYNTHETIC: BETA10 0x100d0660
// LegoSoundManager::`scalar deleting destructor'
private: private:
void Init(); void Init();
void Destroy(MxBool p_fromDestructor); void Destroy(MxBool p_fromDestructor);

View File

@ -28,9 +28,11 @@ class LegoTranInfoList : public MxPtrList<LegoTranInfo> {
// class MxPtrListCursor<LegoTranInfo> // class MxPtrListCursor<LegoTranInfo>
// VTABLE: LEGO1 0x100d8d20 // VTABLE: LEGO1 0x100d8d20
// VTABLE: BETA10 0x101bad70
// SIZE 0x10 // SIZE 0x10
class LegoTranInfoListCursor : public MxPtrListCursor<LegoTranInfo> { class LegoTranInfoListCursor : public MxPtrListCursor<LegoTranInfo> {
public: public:
// FUNCTION: BETA10 0x100496d0
LegoTranInfoListCursor(LegoTranInfoList* p_list) : MxPtrListCursor<LegoTranInfo>(p_list) {} LegoTranInfoListCursor(LegoTranInfoList* p_list) : MxPtrListCursor<LegoTranInfo>(p_list) {}
}; };
@ -62,9 +64,14 @@ class LegoTranInfoListCursor : public MxPtrListCursor<LegoTranInfo> {
// MxPtrList<LegoTranInfo>::`scalar deleting destructor' // MxPtrList<LegoTranInfo>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100612f0 // SYNTHETIC: LEGO1 0x100612f0
// SYNTHETIC: BETA10 0x100498c0
// LegoTranInfoListCursor::`scalar deleting destructor' // LegoTranInfoListCursor::`scalar deleting destructor'
// SYNTHETIC: BETA10 0x10049770
// MxPtrListCursor<LegoTranInfo>::MxPtrListCursor<LegoTranInfo>
// FUNCTION: LEGO1 0x10061360 // FUNCTION: LEGO1 0x10061360
// FUNCTION: BETA10 0x10049910
// MxPtrListCursor<LegoTranInfo>::~MxPtrListCursor<LegoTranInfo> // MxPtrListCursor<LegoTranInfo>::~MxPtrListCursor<LegoTranInfo>
// SYNTHETIC: LEGO1 0x100613b0 // SYNTHETIC: LEGO1 0x100613b0
@ -77,6 +84,7 @@ class LegoTranInfoListCursor : public MxPtrListCursor<LegoTranInfo> {
// MxListCursor<LegoTranInfo *>::~MxListCursor<LegoTranInfo *> // MxListCursor<LegoTranInfo *>::~MxListCursor<LegoTranInfo *>
// FUNCTION: LEGO1 0x100614e0 // FUNCTION: LEGO1 0x100614e0
// FUNCTION: BETA10 0x10049ab0
// LegoTranInfoListCursor::~LegoTranInfoListCursor // LegoTranInfoListCursor::~LegoTranInfoListCursor
#endif // LEGOTRANINFOLIST_H #endif // LEGOTRANINFOLIST_H

View File

@ -32,6 +32,14 @@ enum Cursor {
e_cursorNone e_cursorNone
}; };
enum GameEvent {
e_hitActor,
e_skeletonKick,
e_raceFinished,
e_badEnding,
e_goodEnding
};
class BoundingSphere; class BoundingSphere;
class MxAtomId; class MxAtomId;
class LegoEntity; class LegoEntity;
@ -71,7 +79,7 @@ LegoNamedTexture* ReadNamedTexture(LegoStorage* p_storage);
void WriteDefaultTexture(LegoStorage* p_storage, const char* p_name); void WriteDefaultTexture(LegoStorage* p_storage, const char* p_name);
void WriteNamedTexture(LegoStorage* p_storage, LegoNamedTexture* p_namedTexture); void WriteNamedTexture(LegoStorage* p_storage, LegoNamedTexture* p_namedTexture);
void LoadFromNamedTexture(LegoNamedTexture* p_namedTexture); void LoadFromNamedTexture(LegoNamedTexture* p_namedTexture);
void HitActorEvent(); void EmitGameEvent(GameEvent p_event);
// FUNCTION: BETA10 0x100260a0 // FUNCTION: BETA10 0x100260a0
inline void StartIsleAction(IsleScript::Script p_objectId) inline void StartIsleAction(IsleScript::Script p_objectId)

View File

@ -17,41 +17,60 @@ extern const char* g_varVISIBILITY;
extern const char* g_varCAMERALOCATION; extern const char* g_varCAMERALOCATION;
extern const char* g_varCURSOR; extern const char* g_varCURSOR;
extern const char* g_varWHOAMI; extern const char* g_varWHOAMI;
extern const char* g_varDEBUG;
// VTABLE: LEGO1 0x100d86c8 // VTABLE: LEGO1 0x100d86c8
// VTABLE: BETA10 0x101bc980
// SIZE 0x24 // SIZE 0x24
class VisibilityVariable : public MxVariable { class VisibilityVariable : public MxVariable {
public: public:
// FUNCTION: BETA10 0x10093470
VisibilityVariable() { m_key = g_varVISIBILITY; } VisibilityVariable() { m_key = g_varVISIBILITY; }
void SetValue(const char* p_value) override; // vtable+0x04 void SetValue(const char* p_value) override; // vtable+0x04
}; };
// VTABLE: LEGO1 0x100d86b8 // VTABLE: LEGO1 0x100d86b8
// VTABLE: BETA10 0x101bc990
// SIZE 0x24 // SIZE 0x24
class CameraLocationVariable : public MxVariable { class CameraLocationVariable : public MxVariable {
public: public:
// FUNCTION: BETA10 0x10093510
CameraLocationVariable() { m_key = g_varCAMERALOCATION; } CameraLocationVariable() { m_key = g_varCAMERALOCATION; }
void SetValue(const char* p_value) override; // vtable+0x04 void SetValue(const char* p_value) override; // vtable+0x04
}; };
// VTABLE: LEGO1 0x100d86a8 // VTABLE: LEGO1 0x100d86a8
// VTABLE: BETA10 0x101bc9a0
// SIZE 0x24 // SIZE 0x24
class CursorVariable : public MxVariable { class CursorVariable : public MxVariable {
public: public:
// FUNCTION: BETA10 0x100935b0
CursorVariable() { m_key = g_varCURSOR; } CursorVariable() { m_key = g_varCURSOR; }
void SetValue(const char* p_value) override; // vtable+0x04 void SetValue(const char* p_value) override; // vtable+0x04
}; };
// VTABLE: LEGO1 0x100d8698 // VTABLE: LEGO1 0x100d8698
// VTABLE: BETA10 0x101bc9b0
// SIZE 0x24 // SIZE 0x24
class WhoAmIVariable : public MxVariable { class WhoAmIVariable : public MxVariable {
public: public:
// FUNCTION: BETA10 0x10093650
WhoAmIVariable() { m_key = g_varWHOAMI; } WhoAmIVariable() { m_key = g_varWHOAMI; }
void SetValue(const char* p_value) override; // vtable+0x04 void SetValue(const char* p_value) override; // vtable+0x04
}; };
// VTABLE: BETA10 0x101bc9c0
// SIZE 0x24
class DebugVariable : public MxVariable {
public:
// FUNCTION: BETA10 0x100936f0
DebugVariable() { m_key = g_varDEBUG; }
void SetValue(const char* p_value) override; // vtable+0x04
};
#endif // LEGOVARIABLES_H #endif // LEGOVARIABLES_H

View File

@ -27,6 +27,7 @@ class Renderer;
} }
// VTABLE: LEGO1 0x100d9c88 // VTABLE: LEGO1 0x100d9c88
// VTABLE: BETA10 0x101bef08
// SIZE 0x590 // SIZE 0x590
class LegoVideoManager : public MxVideoManager { class LegoVideoManager : public MxVideoManager {
public: public:
@ -49,6 +50,7 @@ class LegoVideoManager : public MxVideoManager {
virtual MxPresenter* GetPresenterAt(MxS32 p_x, MxS32 p_y); // vtable+0x38 virtual MxPresenter* GetPresenterAt(MxS32 p_x, MxS32 p_y); // vtable+0x38
// FUNCTION: LEGO1 0x1007ab10 // FUNCTION: LEGO1 0x1007ab10
// FUNCTION: BETA10 0x100d8010
virtual LegoPhonemeList* GetPhonemeList() { return m_phonemeRefList; } // vtable+0x3c virtual LegoPhonemeList* GetPhonemeList() { return m_phonemeRefList; } // vtable+0x3c
void SetSkyColor(float p_red, float p_green, float p_blue); void SetSkyColor(float p_red, float p_green, float p_blue);
@ -75,6 +77,10 @@ class LegoVideoManager : public MxVideoManager {
void SetUnk0x554(MxBool p_unk0x554) { m_unk0x554 = p_unk0x554; } void SetUnk0x554(MxBool p_unk0x554) { m_unk0x554 = p_unk0x554; }
// SYNTHETIC: LEGO1 0x1007ab20
// SYNTHETIC: BETA10 0x100d8040
// LegoVideoManager::`scalar deleting destructor'
private: private:
MxResult CreateDirect3D(); MxResult CreateDirect3D();
MxResult ConfigureD3DRM(); MxResult ConfigureD3DRM();
@ -135,7 +141,4 @@ class LegoVideoManager : public MxVideoManager {
friend class DebugViewer; friend class DebugViewer;
}; };
// SYNTHETIC: LEGO1 0x1007ab20
// LegoVideoManager::`scalar deleting destructor'
#endif // LEGOVIDEOMANAGER_H #endif // LEGOVIDEOMANAGER_H

View File

@ -16,12 +16,15 @@ class LegoWorld;
// class MxPtrList<LegoWorld> // class MxPtrList<LegoWorld>
// VTABLE: LEGO1 0x100d8680 // VTABLE: LEGO1 0x100d8680
// VTABLE: BETA10 0x101bc900
// SIZE 0x18 // SIZE 0x18
class LegoWorldList : public MxPtrList<LegoWorld> { class LegoWorldList : public MxPtrList<LegoWorld> {
public: public:
// FUNCTION: BETA10 0x10092ce0
LegoWorldList(MxBool p_ownership = FALSE) : MxPtrList<LegoWorld>(p_ownership) {} LegoWorldList(MxBool p_ownership = FALSE) : MxPtrList<LegoWorld>(p_ownership) {}
// FUNCTION: LEGO1 0x100598d0 // FUNCTION: LEGO1 0x100598d0
// FUNCTION: BETA10 0x10092d80
MxS8 Compare(LegoWorld* p_a, LegoWorld* p_b) override { return p_a == p_b ? 0 : p_a < p_b ? -1 : 1; } // vtable+0x14 MxS8 Compare(LegoWorld* p_a, LegoWorld* p_b) override { return p_a == p_b ? 0 : p_a < p_b ? -1 : 1; } // vtable+0x14
// SYNTHETIC: LEGO1 0x10059a00 // SYNTHETIC: LEGO1 0x10059a00

View File

@ -53,7 +53,7 @@ void Disable(MxBool p_disable, MxU16 p_flags);
LegoROI* FindROI(const char* p_name); LegoROI* FindROI(const char* p_name);
void SetROIVisible(const char* p_name, MxBool p_visible); void SetROIVisible(const char* p_name, MxBool p_visible);
void SetUserActor(LegoPathActor* p_userActor); void SetUserActor(LegoPathActor* p_userActor);
MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction); MxResult StartActionIfInitialized(MxDSAction& p_dsAction);
void DeleteAction(); void DeleteAction();
LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid); LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid);
MxDSAction& GetCurrentAction(); MxDSAction& GetCurrentAction();

View File

@ -39,7 +39,7 @@ class PizzaMissionState : public LegoState {
m_unk0x08 = 1; m_unk0x08 = 1;
m_finishTimes = p_finishTimes; m_finishTimes = p_finishTimes;
m_startTime = INT_MIN; m_startTime = INT_MIN;
m_unk0x14 = 1; m_counter = 1;
m_score = LegoState::e_grey; m_score = LegoState::e_grey;
m_hiScore = LegoState::e_grey; m_hiScore = LegoState::e_grey;
m_actions = p_actions; m_actions = p_actions;
@ -54,7 +54,7 @@ class PizzaMissionState : public LegoState {
m_unk0x08 = p_mission.m_unk0x08; m_unk0x08 = p_mission.m_unk0x08;
m_finishTimes = p_mission.m_finishTimes; m_finishTimes = p_mission.m_finishTimes;
m_startTime = p_mission.m_startTime; m_startTime = p_mission.m_startTime;
m_unk0x14 = p_mission.m_unk0x14; m_counter = p_mission.m_counter;
m_score = p_mission.m_score; m_score = p_mission.m_score;
m_hiScore = p_mission.m_hiScore; m_hiScore = p_mission.m_hiScore;
m_actions = p_mission.m_actions; m_actions = p_mission.m_actions;
@ -102,12 +102,24 @@ class PizzaMissionState : public LegoState {
undefined m_unk0x08; // 0x08 undefined m_unk0x08; // 0x08
MxLong* m_finishTimes; // 0x0c MxLong* m_finishTimes; // 0x0c
MxLong m_startTime; // 0x10 MxLong m_startTime; // 0x10
MxS16 m_unk0x14; // 0x14 MxS16 m_counter; // 0x14
MxS16 m_score; // 0x16 MxS16 m_score; // 0x16
MxS16 m_hiScore; // 0x18 MxS16 m_hiScore; // 0x18
IsleScript::Script* m_actions; // 0x1c IsleScript::Script* m_actions; // 0x1c
}; };
enum {
e_none = 0,
e_introduction = 1,
e_waitAcceptingQuest = 2,
e_started = 3,
e_delivering = 4,
e_arrivedAtDestination = 5,
e_suggestHelicopter = 6,
e_transitionToAct2 = 8,
e_timeoutAcceptingQuest = 9,
};
PizzaMissionState(); PizzaMissionState();
// FUNCTION: LEGO1 0x10039290 // FUNCTION: LEGO1 0x10039290
@ -142,7 +154,7 @@ class PizzaMissionState : public LegoState {
MxS16 GetActorState(); MxS16 GetActorState();
PizzeriaState* m_pizzeriaState; // 0x08 PizzeriaState* m_pizzeriaState; // 0x08
undefined4 m_unk0x0c; // 0x0c MxU32 m_state; // 0x0c
Mission m_missions[5]; // 0x10 Mission m_missions[5]; // 0x10
MxU32 m_playedAction; // 0xb0 MxU32 m_playedAction; // 0xb0
@ -189,8 +201,8 @@ class Pizza : public IsleActor {
MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param) override; // vtable+0x80 MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param) override; // vtable+0x80
void CreateState(); void CreateState();
void FUN_10038220(IsleScript::Script p_objectId); void Start(IsleScript::Script p_objectId);
void FUN_100382b0(); void Reset();
void StopActions(); void StopActions();
void PlayAction(MxU32 p_objectId, MxBool p_param7); void PlayAction(MxU32 p_objectId, MxBool p_param7);
@ -207,7 +219,7 @@ class Pizza : public IsleActor {
IsleScript::Script m_speechAction; // 0x8c IsleScript::Script m_speechAction; // 0x8c
MxLong m_startTime; // 0x90 MxLong m_startTime; // 0x90
MxLong m_duration; // 0x94 MxLong m_duration; // 0x94
MxBool m_unk0x98; // 0x98 MxBool m_playedLocationAnimation; // 0x98
}; };
#endif // PIZZA_H #endif // PIZZA_H

View File

@ -631,7 +631,7 @@ MxU32 Act2Actor::FUN_10019700(MxFloat p_param)
MxFloat time = p_param - (m_unk0x2c - m_shootAnim->GetDuration()); MxFloat time = p_param - (m_unk0x2c - m_shootAnim->GetDuration());
for (MxS32 i = 0; i < root->GetNumChildren(); i++) { for (MxS32 i = 0; i < root->GetNumChildren(); i++) {
LegoROI::FUN_100a8e80(root->GetChild(i), matrix, time, m_shootAnim->GetROIMap()); LegoROI::ApplyAnimationTransformation(root->GetChild(i), matrix, time, m_shootAnim->GetROIMap());
} }
return FALSE; return FALSE;

View File

@ -4,9 +4,9 @@
#include "act3ammo.h" #include "act3ammo.h"
#include "anim/legoanim.h" #include "anim/legoanim.h"
#include "define.h" #include "define.h"
#include "legoanimpresenter.h"
#include "legobuildingmanager.h" #include "legobuildingmanager.h"
#include "legocachesoundmanager.h" #include "legocachesoundmanager.h"
#include "legolocomotionanimpresenter.h"
#include "legopathedgecontainer.h" #include "legopathedgecontainer.h"
#include "legoplantmanager.h" #include "legoplantmanager.h"
#include "legoplants.h" #include "legoplants.h"
@ -639,7 +639,7 @@ void Act3Brickster::Animate(float p_time)
float time = p_time - (m_unk0x50 - m_shootAnim->GetDuration()); float time = p_time - (m_unk0x50 - m_shootAnim->GetDuration());
for (MxS32 i = 0; i < root->GetNumChildren(); i++) { for (MxS32 i = 0; i < root->GetNumChildren(); i++) {
LegoROI::FUN_100a8e80(root->GetChild(i), local70, time, m_shootAnim->GetROIMap()); LegoROI::ApplyAnimationTransformation(root->GetChild(i), local70, time, m_shootAnim->GetROIMap());
} }
} }
@ -686,7 +686,7 @@ void Act3Brickster::Animate(float p_time)
float time = p_time - (m_unk0x50 - m_shootAnim->GetDuration()); float time = p_time - (m_unk0x50 - m_shootAnim->GetDuration());
for (MxS32 i = 0; i < root->GetNumChildren(); i++) { for (MxS32 i = 0; i < root->GetNumChildren(); i++) {
LegoROI::FUN_100a8e80(root->GetChild(i), locale4, time, m_shootAnim->GetROIMap()); LegoROI::ApplyAnimationTransformation(root->GetChild(i), locale4, time, m_shootAnim->GetROIMap());
} }
} }
@ -1187,7 +1187,7 @@ void Act3Shark::Animate(float p_time)
vec = m_unk0x3c; vec = m_unk0x3c;
LegoTreeNode* node = m_unk0x34->GetAnimTreePtr()->GetRoot(); LegoTreeNode* node = m_unk0x34->GetAnimTreePtr()->GetRoot();
LegoROI::FUN_100a8e80(node, mat, duration, m_unk0x34->GetROIMap()); LegoROI::ApplyAnimationTransformation(node, mat, duration, m_unk0x34->GetROIMap());
} }
else { else {
roiMap[1] = m_unk0x38; roiMap[1] = m_unk0x38;

View File

@ -44,7 +44,7 @@ Ambulance::Ambulance()
m_atBeachTask = 0; m_atBeachTask = 0;
m_taskState = Ambulance::e_none; m_taskState = Ambulance::e_none;
m_lastAction = IsleScript::c_noneIsle; m_lastAction = IsleScript::c_noneIsle;
m_unk0x172 = 0; m_enableRandomAudio = 0;
m_lastAnimation = IsleScript::c_noneIsle; m_lastAnimation = IsleScript::c_noneIsle;
m_fuel = 1.0; m_fuel = 1.0;
} }
@ -176,7 +176,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param)
m_state->m_state = AmbulanceMissionState::e_enteredAmbulance; m_state->m_state = AmbulanceMissionState::e_enteredAmbulance;
CurrentWorld()->PlaceActor(UserActor()); CurrentWorld()->PlaceActor(UserActor());
HandleClick(); HandleClick();
m_unk0x172 = 0; m_enableRandomAudio = 0;
TickleManager()->RegisterClient(this, 40000); TickleManager()->RegisterClient(this, 40000);
} }
else if (objectId == IsleScript::c_hpz047pe_RunAnim || objectId == IsleScript::c_hpz048pe_RunAnim || objectId == IsleScript::c_hpz049bd_RunAnim || objectId == IsleScript::c_hpz053pa_RunAnim) { else if (objectId == IsleScript::c_hpz047pe_RunAnim || objectId == IsleScript::c_hpz048pe_RunAnim || objectId == IsleScript::c_hpz049bd_RunAnim || objectId == IsleScript::c_hpz053pa_RunAnim) {
@ -201,7 +201,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param)
CurrentWorld()->PlaceActor(UserActor()); CurrentWorld()->PlaceActor(UserActor());
HandleClick(); HandleClick();
SpawnPlayer(LegoGameState::e_pizzeriaExterior, TRUE, 0); SpawnPlayer(LegoGameState::e_pizzeriaExterior, TRUE, 0);
m_unk0x172 = 0; m_enableRandomAudio = 0;
TickleManager()->RegisterClient(this, 40000); TickleManager()->RegisterClient(this, 40000);
if (m_atPoliceTask != 0) { if (m_atPoliceTask != 0) {
@ -225,7 +225,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param)
CurrentWorld()->PlaceActor(UserActor()); CurrentWorld()->PlaceActor(UserActor());
HandleClick(); HandleClick();
SpawnPlayer(LegoGameState::e_policeExited, TRUE, 0); SpawnPlayer(LegoGameState::e_policeExited, TRUE, 0);
m_unk0x172 = 0; m_enableRandomAudio = 0;
TickleManager()->RegisterClient(this, 40000); TickleManager()->RegisterClient(this, 40000);
if (m_atBeachTask != 0) { if (m_atBeachTask != 0) {
@ -440,7 +440,7 @@ MxLong Ambulance::HandleControl(LegoControlManagerNotificationParam& p_param)
{ {
MxLong result = 0; MxLong result = 0;
if (p_param.m_unk0x28 == 1) { if (p_param.m_enabledChild == 1) {
switch (p_param.m_clickedObjectId) { switch (p_param.m_clickedObjectId) {
case IsleScript::c_AmbulanceArms_Ctl: case IsleScript::c_AmbulanceArms_Ctl:
Exit(); Exit();
@ -457,7 +457,7 @@ MxLong Ambulance::HandleControl(LegoControlManagerNotificationParam& p_param)
case IsleScript::c_AmbulanceHorn_Ctl: case IsleScript::c_AmbulanceHorn_Ctl:
MxSoundPresenter* presenter = MxSoundPresenter* presenter =
(MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "AmbulanceHorn_Sound"); (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "AmbulanceHorn_Sound");
presenter->Enable(p_param.m_unk0x28); presenter->Enable(p_param.m_enabledChild);
break; break;
} }
} }
@ -516,8 +516,8 @@ void Ambulance::ActivateSceneActions()
// FUNCTION: BETA10 0x100237df // FUNCTION: BETA10 0x100237df
MxResult Ambulance::Tickle() MxResult Ambulance::Tickle()
{ {
if (m_unk0x172 == 0) { if (m_enableRandomAudio == 0) {
m_unk0x172 = 1; m_enableRandomAudio = 1;
} }
else if (m_lastAction == IsleScript::c_noneIsle) { else if (m_lastAction == IsleScript::c_noneIsle) {
IsleScript::Script objectId; IsleScript::Script objectId;

View File

@ -81,7 +81,7 @@ MxLong Bike::HandleControl(LegoControlManagerNotificationParam& p_param)
{ {
MxLong result = 0; MxLong result = 0;
if (p_param.m_unk0x28 == 1) { if (p_param.m_enabledChild == 1) {
switch (p_param.m_clickedObjectId) { switch (p_param.m_clickedObjectId) {
case IsleScript::c_BikeArms_Ctl: case IsleScript::c_BikeArms_Ctl:
Exit(); Exit();
@ -97,7 +97,7 @@ MxLong Bike::HandleControl(LegoControlManagerNotificationParam& p_param)
case IsleScript::c_BikeHorn_Ctl: case IsleScript::c_BikeHorn_Ctl:
MxSoundPresenter* presenter = MxSoundPresenter* presenter =
(MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "BikeHorn_Sound"); (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "BikeHorn_Sound");
presenter->Enable(p_param.m_unk0x28); presenter->Enable(p_param.m_enabledChild);
break; break;
} }
} }

View File

@ -49,7 +49,7 @@ MxLong InfoCenterEntity::HandleClick(LegoEventNotificationParam& p_param)
} }
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle); Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
isle->FUN_10033350(); isle->SwitchToInfocenter();
isle->SetDestLocation(LegoGameState::Area::e_infomain); isle->SetDestLocation(LegoGameState::Area::e_infomain);
Act1State* act1state = (Act1State*) GameState()->GetState("Act1State"); Act1State* act1state = (Act1State*) GameState()->GetState("Act1State");

View File

@ -124,7 +124,7 @@ MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param)
{ {
MxLong result = 0; MxLong result = 0;
if (p_param.m_unk0x28 == 1) { if (p_param.m_enabledChild == 1) {
switch (p_param.m_clickedObjectId) { switch (p_param.m_clickedObjectId) {
case IsleScript::c_DuneCarArms_Ctl: case IsleScript::c_DuneCarArms_Ctl:
Exit(); Exit();
@ -140,7 +140,7 @@ MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param)
case IsleScript::c_DuneCarHorn_Ctl: case IsleScript::c_DuneCarHorn_Ctl:
MxSoundPresenter* presenter = MxSoundPresenter* presenter =
(MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "DuneCarHorn_Sound"); (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "DuneCarHorn_Sound");
presenter->Enable(p_param.m_unk0x28); presenter->Enable(p_param.m_enabledChild);
break; break;
} }
} }

View File

@ -82,7 +82,7 @@ void Helicopter::Exit()
if (GameState()->GetCurrentAct() == LegoGameState::e_act1) { if (GameState()->GetCurrentAct() == LegoGameState::e_act1) {
SpawnPlayer( SpawnPlayer(
LegoGameState::e_unk40, LegoGameState::e_helicopterSpawn,
TRUE, TRUE,
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3 IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
); );
@ -189,7 +189,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
break; break;
} }
if (p_param.m_unk0x28 == 1) { if (p_param.m_enabledChild == 1) {
MxU32 isPizza = FALSE; MxU32 isPizza = FALSE;
switch (p_param.m_clickedObjectId) { switch (p_param.m_clickedObjectId) {
@ -426,7 +426,7 @@ void Helicopter::Animate(float p_time)
v2 *= f2; v2 *= f2;
v2 += v1; v2 += v1;
m_world->GetCameraController()->FUN_100123e0(mat, 0); m_world->GetCameraController()->TransformPointOfView(mat, 0);
} }
else { else {
if (m_state->m_unk0x08 == 4) { if (m_state->m_unk0x08 == 4) {
@ -459,7 +459,7 @@ void Helicopter::FUN_100042a0(const Matrix4& p_matrix)
// the typecast makes this function match for unknown reasons // the typecast makes this function match for unknown reasons
Vector3 vec6((const float*) m_unk0x1a8[3]); // locala0 // esp+0x28 Vector3 vec6((const float*) m_unk0x1a8[3]); // locala0 // esp+0x28
m_world->GetCameraController()->FUN_100123b0(local48); m_world->GetCameraController()->GetPointOfView(local48);
m_unk0x1a8.SetIdentity(); m_unk0x1a8.SetIdentity();
local90 = p_matrix; local90 = p_matrix;

View File

@ -355,7 +355,7 @@ void IslePathActor::RegisterSpawnLocations()
JukeboxScript::c_PoliceStation_Music JukeboxScript::c_PoliceStation_Music
); );
g_spawnLocations[16] = SpawnLocation( g_spawnLocations[16] = SpawnLocation(
LegoGameState::e_unk40, LegoGameState::e_helicopterSpawn,
g_isleScript, g_isleScript,
0, 0,
"edg02_51", "edg02_51",
@ -379,7 +379,7 @@ void IslePathActor::RegisterSpawnLocations()
JukeboxScript::c_noneJukebox JukeboxScript::c_noneJukebox
); );
g_spawnLocations[18] = SpawnLocation( g_spawnLocations[18] = SpawnLocation(
LegoGameState::e_unk43, LegoGameState::e_dunebuggySpawn,
g_isleScript, g_isleScript,
0, 0,
"edg02_35", "edg02_35",
@ -391,7 +391,7 @@ void IslePathActor::RegisterSpawnLocations()
JukeboxScript::c_noneJukebox JukeboxScript::c_noneJukebox
); );
g_spawnLocations[19] = SpawnLocation( g_spawnLocations[19] = SpawnLocation(
LegoGameState::e_unk44, LegoGameState::e_racecarSpawn,
g_isleScript, g_isleScript,
0, 0,
"EDG03_01", "EDG03_01",
@ -403,7 +403,7 @@ void IslePathActor::RegisterSpawnLocations()
JukeboxScript::c_noneJukebox JukeboxScript::c_noneJukebox
); );
g_spawnLocations[20] = SpawnLocation( g_spawnLocations[20] = SpawnLocation(
LegoGameState::e_unk45, LegoGameState::e_jetskiSpawn,
g_isleScript, g_isleScript,
0, 0,
"edg10_70", "edg10_70",
@ -475,7 +475,7 @@ void IslePathActor::RegisterSpawnLocations()
JukeboxScript::c_noneJukebox JukeboxScript::c_noneJukebox
); );
g_spawnLocations[26] = SpawnLocation( g_spawnLocations[26] = SpawnLocation(
LegoGameState::e_unk52, LegoGameState::e_towTrackHookedUp,
g_isleScript, g_isleScript,
0, 0,
"edg02_19", "edg02_19",

View File

@ -69,7 +69,7 @@ void Jetski::Animate(float p_time)
// FUNCTION: LEGO1 0x1007e6f0 // FUNCTION: LEGO1 0x1007e6f0
void Jetski::Exit() void Jetski::Exit()
{ {
SpawnPlayer(LegoGameState::e_unk45, FALSE, c_spawnBit1 | c_playMusic | c_spawnBit3); SpawnPlayer(LegoGameState::e_jetskiSpawn, FALSE, c_spawnBit1 | c_playMusic | c_spawnBit3);
IslePathActor::Exit(); IslePathActor::Exit();
GameState()->m_currentArea = LegoGameState::e_jetski; GameState()->m_currentArea = LegoGameState::e_jetski;
RemoveFromWorld(); RemoveFromWorld();
@ -139,7 +139,7 @@ void Jetski::RemoveFromWorld()
// FUNCTION: LEGO1 0x1007e8e0 // FUNCTION: LEGO1 0x1007e8e0
MxLong Jetski::HandleControl(LegoControlManagerNotificationParam& p_param) MxLong Jetski::HandleControl(LegoControlManagerNotificationParam& p_param)
{ {
if (p_param.m_unk0x28 == 1 && CurrentWorld()->IsA("Isle")) { if (p_param.m_enabledChild == 1 && CurrentWorld()->IsA("Isle")) {
switch (p_param.m_clickedObjectId) { switch (p_param.m_clickedObjectId) {
case IsleScript::c_JetskiArms_Ctl: case IsleScript::c_JetskiArms_Ctl:
Exit(); Exit();

View File

@ -117,7 +117,7 @@ MxLong Motocycle::HandleControl(LegoControlManagerNotificationParam& p_param)
{ {
MxLong result = 0; MxLong result = 0;
if (p_param.m_unk0x28 == 1) { if (p_param.m_enabledChild == 1) {
switch (p_param.m_clickedObjectId) { switch (p_param.m_clickedObjectId) {
case IsleScript::c_MotoBikeArms_Ctl: case IsleScript::c_MotoBikeArms_Ctl:
Exit(); Exit();

View File

@ -137,7 +137,7 @@ Pizza::Pizza()
m_skateBoard = NULL; m_skateBoard = NULL;
m_act1state = NULL; m_act1state = NULL;
m_speechAction = IsleScript::c_noneIsle; m_speechAction = IsleScript::c_noneIsle;
m_unk0x98 = FALSE; m_playedLocationAnimation = FALSE;
m_startTime = INT_MIN; m_startTime = INT_MIN;
} }
@ -177,11 +177,11 @@ void Pizza::CreateState()
// FUNCTION: LEGO1 0x10038220 // FUNCTION: LEGO1 0x10038220
// FUNCTION: BETA10 0x100edb81 // FUNCTION: BETA10 0x100edb81
void Pizza::FUN_10038220(IsleScript::Script p_objectId) void Pizza::Start(IsleScript::Script p_objectId)
{ {
AnimationManager()->FUN_10064740(NULL); AnimationManager()->FUN_10064740(NULL);
m_mission = m_state->GetMission(GameState()->GetActorId()); m_mission = m_state->GetMission(GameState()->GetActorId());
m_state->m_unk0x0c = 1; m_state->m_state = PizzaMissionState::e_introduction;
m_act1state->m_state = Act1State::e_pizza; m_act1state->m_state = Act1State::e_pizza;
m_mission->m_startTime = INT_MIN; m_mission->m_startTime = INT_MIN;
g_isleFlags &= ~Isle::c_playMusic; g_isleFlags &= ~Isle::c_playMusic;
@ -193,22 +193,22 @@ void Pizza::FUN_10038220(IsleScript::Script p_objectId)
// FUNCTION: LEGO1 0x100382b0 // FUNCTION: LEGO1 0x100382b0
// FUNCTION: BETA10 0x100edc9b // FUNCTION: BETA10 0x100edc9b
void Pizza::FUN_100382b0() void Pizza::Reset()
{ {
if (m_state->m_unk0x0c != 8) { if (m_state->m_state != PizzaMissionState::e_transitionToAct2) {
if (m_speechAction != IsleScript::c_noneIsle) { if (m_speechAction != IsleScript::c_noneIsle) {
InvokeAction(Extra::e_stop, *g_isleScript, m_speechAction, NULL); InvokeAction(Extra::e_stop, *g_isleScript, m_speechAction, NULL);
} }
m_act1state->m_state = Act1State::e_none; m_act1state->m_state = Act1State::e_none;
m_state->m_unk0x0c = 0; m_state->m_state = PizzaMissionState::e_none;
UserActor()->SetActorState(LegoPathActor::c_initial); UserActor()->SetActorState(LegoPathActor::c_initial);
g_isleFlags |= Isle::c_playMusic; g_isleFlags |= Isle::c_playMusic;
AnimationManager()->EnableCamAnims(TRUE); AnimationManager()->EnableCamAnims(TRUE);
AnimationManager()->FUN_1005f6d0(TRUE); AnimationManager()->FUN_1005f6d0(TRUE);
m_mission->m_startTime = INT_MIN; m_mission->m_startTime = INT_MIN;
m_mission = NULL; m_mission = NULL;
m_unk0x98 = FALSE; m_playedLocationAnimation = FALSE;
m_speechAction = IsleScript::c_noneIsle; m_speechAction = IsleScript::c_noneIsle;
BackgroundAudioManager()->RaiseVolume(); BackgroundAudioManager()->RaiseVolume();
TickleManager()->UnregisterClient(this); TickleManager()->UnregisterClient(this);
@ -237,14 +237,14 @@ void Pizza::StopActions()
// FUNCTION: BETA10 0x100edd10 // FUNCTION: BETA10 0x100edd10
MxLong Pizza::HandleClick() MxLong Pizza::HandleClick()
{ {
if (m_state->m_unk0x0c == 1) { if (m_state->m_state == PizzaMissionState::e_introduction) {
m_state->m_unk0x0c = 2; m_state->m_state = PizzaMissionState::e_waitAcceptingQuest;
m_mission->m_startTime = Timer()->GetTime(); m_mission->m_startTime = Timer()->GetTime();
TickleManager()->RegisterClient(this, 200); TickleManager()->RegisterClient(this, 200);
AnimationManager()->FUN_10061010(FALSE); AnimationManager()->FUN_10061010(FALSE);
} }
if (m_state->m_unk0x0c == 2) { if (m_state->m_state == PizzaMissionState::e_waitAcceptingQuest) {
m_act1state->m_state = Act1State::e_pizza; m_act1state->m_state = Act1State::e_pizza;
if (m_skateBoard == NULL) { if (m_skateBoard == NULL) {
@ -266,7 +266,7 @@ MxLong Pizza::HandleClick()
} }
PlayAction(action, TRUE); PlayAction(action, TRUE);
m_state->m_unk0x0c = 3; m_state->m_state = PizzaMissionState::e_started;
PlayMusic(JukeboxScript::c_PizzaMission_Music); PlayMusic(JukeboxScript::c_PizzaMission_Music);
return 1; return 1;
} }
@ -278,12 +278,12 @@ MxLong Pizza::HandleClick()
// FUNCTION: BETA10 0x100ede53 // FUNCTION: BETA10 0x100ede53
MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param) MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param)
{ {
if (m_state->m_unk0x0c == 4) { if (m_state->m_state == PizzaMissionState::e_delivering) {
MxLong time = Timer()->GetTime() - m_mission->m_startTime; MxLong time = Timer()->GetTime() - m_mission->m_startTime;
if (p_param.GetTrigger() == LegoPathStruct::c_s && p_param.GetData() == 0x12e && if (p_param.GetTrigger() == LegoPathStruct::c_s && p_param.GetData() == 0x12e &&
GameState()->GetActorId() == LegoActor::c_pepper) { GameState()->GetActorId() == LegoActor::c_pepper) {
m_state->m_unk0x0c = 5; m_state->m_state = PizzaMissionState::e_arrivedAtDestination;
m_state->SetPlayedAction(SndanimScript::c_TRS302_OpenJailDoor); m_state->SetPlayedAction(SndanimScript::c_TRS302_OpenJailDoor);
if (time < m_mission->GetRedFinishTime()) { if (time < m_mission->GetRedFinishTime()) {
@ -348,20 +348,20 @@ MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param)
break; break;
} }
m_state->m_unk0x0c = 5; m_state->m_state = PizzaMissionState::e_arrivedAtDestination;
PlayAction(action, TRUE); PlayAction(action, TRUE);
MxTrace("Pizza mission: ending\n"); MxTrace("Pizza mission: ending\n");
} }
else if (p_param.GetTrigger() == LegoPathStruct::c_w) { else if (p_param.GetTrigger() == LegoPathStruct::c_w) {
if (p_param.GetData() == 0x15e && GameState()->GetActorId() == LegoActor::c_pepper) { if (p_param.GetData() == 0x15e && GameState()->GetActorId() == LegoActor::c_pepper) {
if (!m_unk0x98) { if (!m_playedLocationAnimation) {
m_unk0x98 = TRUE; m_playedLocationAnimation = TRUE;
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_pns050p1_RunAnim, NULL); InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_pns050p1_RunAnim, NULL);
} }
} }
else if (p_param.GetData() == 0x15f && GameState()->GetActorId() == LegoActor::c_papa && !m_unk0x98) { else if (p_param.GetData() == 0x15f && GameState()->GetActorId() == LegoActor::c_papa && !m_playedLocationAnimation) {
m_unk0x98 = TRUE; m_playedLocationAnimation = TRUE;
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns050p1_RunAnim, NULL); InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns050p1_RunAnim, NULL);
} }
} }
@ -384,13 +384,13 @@ MxResult Pizza::Tickle()
} }
if (m_mission != NULL && m_mission->m_startTime != INT_MIN) { if (m_mission != NULL && m_mission->m_startTime != INT_MIN) {
if (m_state->m_unk0x0c == 4) { if (m_state->m_state == PizzaMissionState::e_delivering) {
assert(m_mission); assert(m_mission);
if (time > m_mission->m_startTime + m_mission->GetTimeoutTime()) { if (time > m_mission->m_startTime + m_mission->GetTimeoutTime()) {
StopActions(); StopActions();
m_mission->UpdateScore(LegoState::e_grey); m_mission->UpdateScore(LegoState::e_grey);
FUN_100382b0(); Reset();
BackgroundAudioManager()->LowerVolume(); BackgroundAudioManager()->LowerVolume();
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_Avo917In_PlayWav, NULL); InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_Avo917In_PlayWav, NULL);
MxTrace("Pizza mission: timeout, stop\n"); MxTrace("Pizza mission: timeout, stop\n");
@ -421,7 +421,7 @@ MxResult Pizza::Tickle()
} }
} }
} }
else if (m_state->m_unk0x0c == 2) { else if (m_state->m_state == PizzaMissionState::e_waitAcceptingQuest) {
assert(m_mission); assert(m_mission);
if (Timer()->GetTime() > m_mission->m_startTime + 5000) { if (Timer()->GetTime() > m_mission->m_startTime + 5000) {
@ -429,7 +429,7 @@ MxResult Pizza::Tickle()
m_skateBoard->EnableScenePresentation(FALSE); m_skateBoard->EnableScenePresentation(FALSE);
TickleManager()->UnregisterClient(this); TickleManager()->UnregisterClient(this);
m_mission->UpdateScore(LegoState::e_grey); m_mission->UpdateScore(LegoState::e_grey);
m_state->m_unk0x0c = 9; m_state->m_state = PizzaMissionState::e_timeoutAcceptingQuest;
AnimationManager()->FUN_1005f6d0(TRUE); AnimationManager()->FUN_1005f6d0(TRUE);
PlayAction(m_mission->GetUnknownFinishAction(), TRUE); PlayAction(m_mission->GetUnknownFinishAction(), TRUE);
MxTrace("Pizza mission: timeout, declining\n"); MxTrace("Pizza mission: timeout, declining\n");
@ -452,16 +452,16 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
return 1; return 1;
} }
switch (m_state->m_unk0x0c) { switch (m_state->m_state) {
case 1: case PizzaMissionState::e_introduction:
if (m_state->GetPlayedAction() == objectId) { if (m_state->GetPlayedAction() == objectId) {
m_state->m_unk0x0c = 2; m_state->m_state = PizzaMissionState::e_waitAcceptingQuest;
m_mission->m_startTime = Timer()->GetTime(); m_mission->m_startTime = Timer()->GetTime();
TickleManager()->RegisterClient(this, 200); TickleManager()->RegisterClient(this, 200);
MxTrace("Pizza mission: proposed\n"); MxTrace("Pizza mission: proposed\n");
} }
break; break;
case 3: case PizzaMissionState::e_started:
if (m_state->GetPlayedAction() == objectId) { if (m_state->GetPlayedAction() == objectId) {
m_mission->m_startTime = Timer()->GetTime(); m_mission->m_startTime = Timer()->GetTime();
@ -470,7 +470,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
InvokeAction(Extra::e_start, *g_isleScript, mission->GetActions()[i], NULL); InvokeAction(Extra::e_start, *g_isleScript, mission->GetActions()[i], NULL);
} }
m_state->m_unk0x0c = 4; m_state->m_state = PizzaMissionState::e_delivering;
m_state->SetPlayedAction(IsleScript::c_noneIsle); m_state->SetPlayedAction(IsleScript::c_noneIsle);
UserActor()->SetActorState(LegoPathActor::c_initial); UserActor()->SetActorState(LegoPathActor::c_initial);
m_skateBoard->SetPizzaVisible(TRUE); m_skateBoard->SetPizzaVisible(TRUE);
@ -489,7 +489,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
result = 1; result = 1;
} }
break; break;
case 5: case PizzaMissionState::e_arrivedAtDestination:
if (m_state->GetPlayedAction() == objectId) { if (m_state->GetPlayedAction() == objectId) {
StopActions(); StopActions();
@ -497,26 +497,26 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
IsleScript::Script action = IsleScript::c_noneIsle; IsleScript::Script action = IsleScript::c_noneIsle;
if (!((Isle*) CurrentWorld())->HasHelicopter()) { if (!((Isle*) CurrentWorld())->HasHelicopter()) {
switch (m_mission->m_unk0x14) { switch (m_mission->m_counter) {
case 1: case 1:
action = IsleScript::c_pja126br_RunAnim; action = IsleScript::c_pja126br_RunAnim;
m_mission->m_unk0x14++; m_mission->m_counter++;
m_state->m_unk0x0c = 6; m_state->m_state = PizzaMissionState::e_suggestHelicopter;
MxTrace("Pizza mission: succeeds\n"); MxTrace("Pizza mission: succeeds\n");
break; break;
case 2: case 2:
action = IsleScript::c_pja129br_RunAnim; action = IsleScript::c_pja129br_RunAnim;
m_startTime = Timer()->GetTime(); m_startTime = Timer()->GetTime();
m_duration = 500; m_duration = 500;
m_mission->m_unk0x14++; m_mission->m_counter++;
m_state->m_unk0x0c = 6; m_state->m_state = PizzaMissionState::e_suggestHelicopter;
MxTrace("Pizza mission: succeeds\n"); MxTrace("Pizza mission: succeeds\n");
break; break;
case 3: case 3:
action = IsleScript::c_pja131br_RunAnim; action = IsleScript::c_pja131br_RunAnim;
m_startTime = Timer()->GetTime(); m_startTime = Timer()->GetTime();
m_duration = 500; m_duration = 500;
m_state->m_unk0x0c = 6; m_state->m_state = PizzaMissionState::e_suggestHelicopter;
break; break;
} }
} }
@ -524,7 +524,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
action = IsleScript::c_pja132br_RunAnim; action = IsleScript::c_pja132br_RunAnim;
m_startTime = Timer()->GetTime(); m_startTime = Timer()->GetTime();
m_duration = 2300; m_duration = 2300;
m_state->m_unk0x0c = 8; m_state->m_state = PizzaMissionState::e_transitionToAct2;
InputManager()->DisableInputProcessing(); InputManager()->DisableInputProcessing();
InputManager()->SetUnknown336(TRUE); InputManager()->SetUnknown336(TRUE);
MxTrace("Pizza mission: go to Act2\n"); MxTrace("Pizza mission: go to Act2\n");
@ -533,42 +533,42 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
PlayAction(action, TRUE); PlayAction(action, TRUE);
} }
else { else {
FUN_100382b0(); Reset();
m_state->m_unk0x0c = 0; m_state->m_state = PizzaMissionState::e_none;
m_state->SetPlayedAction(IsleScript::c_noneIsle); m_state->SetPlayedAction(IsleScript::c_noneIsle);
} }
} }
break; break;
case 6: case PizzaMissionState::e_suggestHelicopter:
if (m_state->GetPlayedAction() == objectId) { if (m_state->GetPlayedAction() == objectId) {
if (objectId == IsleScript::c_pja126br_RunAnim) { if (objectId == IsleScript::c_pja126br_RunAnim) {
PlayAction(IsleScript::c_pja127br_RunAnim, TRUE); PlayAction(IsleScript::c_pja127br_RunAnim, TRUE); // build helicopter!
m_startTime = Timer()->GetTime(); m_startTime = Timer()->GetTime();
m_duration = 700; m_duration = 700;
} }
else if (objectId == IsleScript::c_pja129br_RunAnim) { else if (objectId == IsleScript::c_pja129br_RunAnim) {
PlayAction(IsleScript::c_pja130br_RunAnim, TRUE); PlayAction(IsleScript::c_pja130br_RunAnim, TRUE); // build helicopter!
} }
else { else {
FUN_100382b0(); Reset();
m_state->m_unk0x0c = 0; m_state->m_state = PizzaMissionState::e_none;
m_state->SetPlayedAction(IsleScript::c_noneIsle); m_state->SetPlayedAction(IsleScript::c_noneIsle);
} }
} }
break; break;
case 8: case PizzaMissionState::e_transitionToAct2:
if (m_state->GetPlayedAction() == objectId) { if (m_state->GetPlayedAction() == objectId) {
m_act1state->m_state = Act1State::e_none; m_act1state->m_state = Act1State::e_none;
m_state->m_unk0x0c = 0; m_state->m_state = PizzaMissionState::e_none;
GameState()->m_currentArea = LegoGameState::e_isle; GameState()->m_currentArea = LegoGameState::e_isle;
TickleManager()->UnregisterClient(this); TickleManager()->UnregisterClient(this);
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_act2main); ((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_act2main);
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
} }
break; break;
case 9: case PizzaMissionState::e_timeoutAcceptingQuest:
if (m_state->GetPlayedAction() == objectId) { if (m_state->GetPlayedAction() == objectId) {
FUN_100382b0(); Reset();
} }
break; break;
} }
@ -594,7 +594,7 @@ void Pizza::PlayAction(MxU32 p_objectId, MxBool p_param7)
// FUNCTION: BETA10 0x100eea25 // FUNCTION: BETA10 0x100eea25
PizzaMissionState::PizzaMissionState() PizzaMissionState::PizzaMissionState()
{ {
m_unk0x0c = 0; m_state = PizzaMissionState::e_none;
m_missions[0] = Mission(LegoActor::c_pepper, 2, g_pepperFinishTimes, g_pepperActions, 4); m_missions[0] = Mission(LegoActor::c_pepper, 2, g_pepperFinishTimes, g_pepperActions, 4);
m_missions[1] = Mission(LegoActor::c_mama, 2, g_mamaFinishTimes, g_mamaActions, 4); m_missions[1] = Mission(LegoActor::c_mama, 2, g_mamaFinishTimes, g_mamaActions, 4);
m_missions[2] = Mission(LegoActor::c_papa, 2, g_papaFinishTimes, g_papaActions, 4); m_missions[2] = Mission(LegoActor::c_papa, 2, g_papaFinishTimes, g_papaActions, 4);
@ -613,7 +613,7 @@ MxResult PizzaMissionState::Serialize(LegoStorage* p_storage)
if (p_storage->IsReadMode()) { if (p_storage->IsReadMode()) {
for (MxS16 i = 0; i < 5; i++) { for (MxS16 i = 0; i < 5; i++) {
p_storage->ReadS16(m_missions[i].m_unk0x06); p_storage->ReadS16(m_missions[i].m_unk0x06);
p_storage->ReadS16(m_missions[i].m_unk0x14); p_storage->ReadS16(m_missions[i].m_counter);
p_storage->ReadS16(m_missions[i].m_score); p_storage->ReadS16(m_missions[i].m_score);
p_storage->ReadS16(m_missions[i].m_hiScore); p_storage->ReadS16(m_missions[i].m_hiScore);
} }
@ -621,7 +621,7 @@ MxResult PizzaMissionState::Serialize(LegoStorage* p_storage)
else if (p_storage->IsWriteMode()) { else if (p_storage->IsWriteMode()) {
for (MxS16 i = 0; i < 5; i++) { for (MxS16 i = 0; i < 5; i++) {
p_storage->WriteS16(m_missions[i].m_unk0x06); p_storage->WriteS16(m_missions[i].m_unk0x06);
p_storage->WriteS16(m_missions[i].m_unk0x14); p_storage->WriteS16(m_missions[i].m_counter);
p_storage->WriteS16(m_missions[i].m_score); p_storage->WriteS16(m_missions[i].m_score);
p_storage->WriteS16(m_missions[i].m_hiScore); p_storage->WriteS16(m_missions[i].m_hiScore);
} }

View File

@ -69,7 +69,7 @@ void Pizzeria::CreateState()
// FUNCTION: BETA10 0x100efc91 // FUNCTION: BETA10 0x100efc91
MxLong Pizzeria::HandleClick() MxLong Pizzeria::HandleClick()
{ {
if (CanExit() && m_pizzaMissionState->m_unk0x0c == 0) { if (CanExit() && m_pizzaMissionState->m_state == PizzaMissionState::e_none) {
if (UserActor()->GetActorId() != GameState()->GetActorId()) { if (UserActor()->GetActorId() != GameState()->GetActorId()) {
if (!UserActor()->IsA("SkateBoard")) { if (!UserActor()->IsA("SkateBoard")) {
((IslePathActor*) UserActor())->Exit(); ((IslePathActor*) UserActor())->Exit();
@ -79,7 +79,7 @@ MxLong Pizzeria::HandleClick()
AnimationManager()->FUN_10061010(FALSE); AnimationManager()->FUN_10061010(FALSE);
Pizza* pizza = (Pizza*) CurrentWorld()->Find(*g_isleScript, IsleScript::c_Pizza_Actor); Pizza* pizza = (Pizza*) CurrentWorld()->Find(*g_isleScript, IsleScript::c_Pizza_Actor);
pizza->FUN_10038220((IsleScript::Script) m_pizzeriaState->NextAction()); pizza->Start((IsleScript::Script) m_pizzeriaState->NextAction());
} }
return 1; return 1;

View File

@ -59,7 +59,7 @@ void SkateBoard::Exit()
if (m_act1state->m_state == Act1State::e_pizza) { if (m_act1state->m_state == Act1State::e_pizza) {
Pizza* pizza = (Pizza*) CurrentWorld()->Find(*g_isleScript, IsleScript::c_Pizza_Actor); Pizza* pizza = (Pizza*) CurrentWorld()->Find(*g_isleScript, IsleScript::c_Pizza_Actor);
pizza->StopActions(); pizza->StopActions();
pizza->FUN_100382b0(); pizza->Reset();
m_pizzaVisible = FALSE; m_pizzaVisible = FALSE;
} }
@ -110,7 +110,7 @@ MxLong SkateBoard::HandleControl(LegoControlManagerNotificationParam& p_param)
{ {
MxU32 result = 0; MxU32 result = 0;
if (p_param.m_unk0x28 == 1 && p_param.m_clickedObjectId == IsleScript::c_SkateArms_Ctl) { if (p_param.m_enabledChild == 1 && p_param.m_clickedObjectId == IsleScript::c_SkateArms_Ctl) {
Exit(); Exit();
GameState()->m_currentArea = LegoGameState::Area::e_vehicleExited; GameState()->m_currentArea = LegoGameState::Area::e_vehicleExited;
result = 1; result = 1;

View File

@ -434,7 +434,7 @@ MxLong TowTrack::HandleClick()
} }
if (m_state->m_state == TowTrackMissionState::e_hookedUp) { if (m_state->m_state == TowTrackMissionState::e_hookedUp) {
SpawnPlayer(LegoGameState::e_unk52, TRUE, 0); SpawnPlayer(LegoGameState::e_towTrackHookedUp, TRUE, 0);
FindROI("rcred")->SetVisibility(FALSE); FindROI("rcred")->SetVisibility(FALSE);
} }
else { else {
@ -485,7 +485,7 @@ MxLong TowTrack::HandleControl(LegoControlManagerNotificationParam& p_param)
{ {
MxLong result = 0; MxLong result = 0;
if (p_param.m_unk0x28 == 1) { if (p_param.m_enabledChild == 1) {
switch (p_param.m_clickedObjectId) { switch (p_param.m_clickedObjectId) {
case IsleScript::c_TowTrackArms_Ctl: case IsleScript::c_TowTrackArms_Ctl:
Exit(); Exit();
@ -501,7 +501,7 @@ MxLong TowTrack::HandleControl(LegoControlManagerNotificationParam& p_param)
break; break;
case IsleScript::c_TowHorn_Ctl: case IsleScript::c_TowHorn_Ctl:
MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "TowHorn_Sound"); MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "TowHorn_Sound");
presenter->Enable(p_param.m_unk0x28); presenter->Enable(p_param.m_enabledChild);
break; break;
} }
} }

View File

@ -5,7 +5,7 @@
#include "legosoundmanager.h" #include "legosoundmanager.h"
#include "legovideomanager.h" #include "legovideomanager.h"
#include "misc.h" #include "misc.h"
#include "mxomni.h" #include "mxmain.h"
#include <vec.h> #include <vec.h>

View File

@ -2,7 +2,7 @@
#include "mxcompositepresenter.h" #include "mxcompositepresenter.h"
#include "mxdsaction.h" #include "mxdsaction.h"
#include "mxomni.h" #include "mxmain.h"
DECOMP_SIZE_ASSERT(Lego3DWavePresenter, 0xa0) DECOMP_SIZE_ASSERT(Lego3DWavePresenter, 0xa0)

View File

@ -7,6 +7,7 @@ DECOMP_SIZE_ASSERT(LegoCacheSoundEntry, 0x08)
DECOMP_SIZE_ASSERT(LegoCacheSoundManager, 0x20) DECOMP_SIZE_ASSERT(LegoCacheSoundManager, 0x20)
// FUNCTION: LEGO1 0x1003cf20 // FUNCTION: LEGO1 0x1003cf20
// STUB: BETA10 0x100d0700
LegoCacheSoundManager::~LegoCacheSoundManager() LegoCacheSoundManager::~LegoCacheSoundManager()
{ {
LegoCacheSound* sound; LegoCacheSound* sound;
@ -28,6 +29,7 @@ LegoCacheSoundManager::~LegoCacheSoundManager()
} }
// FUNCTION: LEGO1 0x1003d050 // FUNCTION: LEGO1 0x1003d050
// STUB: BETA10 0x100652f0
MxResult LegoCacheSoundManager::Tickle() MxResult LegoCacheSoundManager::Tickle()
{ {
#ifdef COMPAT_MODE #ifdef COMPAT_MODE

View File

@ -2,7 +2,7 @@
#include "legosoundmanager.h" #include "legosoundmanager.h"
#include "misc.h" #include "misc.h"
#include "mxomni.h" #include "mxmain.h"
#include <assert.h> #include <assert.h>

View File

@ -98,7 +98,7 @@ void LegoLoadCacheSoundPresenter::DoneTickle()
// FUNCTION: LEGO1 0x10018700 // FUNCTION: LEGO1 0x10018700
MxResult LegoLoadCacheSoundPresenter::PutData() MxResult LegoLoadCacheSoundPresenter::PutData()
{ {
m_criticalSection.Enter(); ENTER(m_criticalSection);
if (m_currentTickleState == e_done) { if (m_currentTickleState == e_done) {
m_cacheSound = SoundManager()->GetCacheSoundManager()->ManageSoundEntry(m_cacheSound); m_cacheSound = SoundManager()->GetCacheSoundManager()->ManageSoundEntry(m_cacheSound);

View File

@ -2,31 +2,35 @@
#include "legocachesoundmanager.h" #include "legocachesoundmanager.h"
#include "mxautolock.h" #include "mxautolock.h"
#include "mxomni.h" #include "mxmain.h"
#include <assert.h> #include <assert.h>
DECOMP_SIZE_ASSERT(LegoSoundManager, 0x44) DECOMP_SIZE_ASSERT(LegoSoundManager, 0x44)
// FUNCTION: LEGO1 0x100298a0 // FUNCTION: LEGO1 0x100298a0
// FUNCTION: BETA10 0x100cffb0
LegoSoundManager::LegoSoundManager() LegoSoundManager::LegoSoundManager()
{ {
Init(); Init();
} }
// FUNCTION: LEGO1 0x10029940 // FUNCTION: LEGO1 0x10029940
// FUNCTION: BETA10 0x100d0027
LegoSoundManager::~LegoSoundManager() LegoSoundManager::~LegoSoundManager()
{ {
Destroy(TRUE); Destroy(TRUE);
} }
// FUNCTION: LEGO1 0x100299a0 // FUNCTION: LEGO1 0x100299a0
// FUNCTION: BETA10 0x100d0099
void LegoSoundManager::Init() void LegoSoundManager::Init()
{ {
m_cacheSoundManager = NULL; m_cacheSoundManager = NULL;
} }
// FUNCTION: LEGO1 0x100299b0 // FUNCTION: LEGO1 0x100299b0
// FUNCTION: BETA10 0x100d00c9
void LegoSoundManager::Destroy(MxBool p_fromDestructor) void LegoSoundManager::Destroy(MxBool p_fromDestructor)
{ {
delete m_cacheSoundManager; delete m_cacheSoundManager;
@ -41,17 +45,19 @@ void LegoSoundManager::Destroy(MxBool p_fromDestructor)
// FUNCTION: BETA10 0x100d0129 // FUNCTION: BETA10 0x100d0129
MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
{ {
MxBool locked = FALSE;
MxResult result = FAILURE; MxResult result = FAILURE;
MxBool locked = FALSE;
if (MxSoundManager::Create(10, FALSE) == SUCCESS) { if (MxSoundManager::Create(10, FALSE) != SUCCESS) {
m_criticalSection.Enter(); goto done;
locked = TRUE;
m_cacheSoundManager = new LegoCacheSoundManager;
assert(m_cacheSoundManager);
result = SUCCESS;
} }
ENTER(m_criticalSection);
locked = TRUE;
m_cacheSoundManager = new LegoCacheSoundManager;
assert(m_cacheSoundManager);
result = SUCCESS;
done: done:
if (result != SUCCESS) { if (result != SUCCESS) {
Destroy(); Destroy();

View File

@ -15,6 +15,7 @@
DECOMP_SIZE_ASSERT(MxBackgroundAudioManager, 0x150) DECOMP_SIZE_ASSERT(MxBackgroundAudioManager, 0x150)
// FUNCTION: LEGO1 0x1007ea90 // FUNCTION: LEGO1 0x1007ea90
// FUNCTION: BETA10 0x100e8530
MxBackgroundAudioManager::MxBackgroundAudioManager() MxBackgroundAudioManager::MxBackgroundAudioManager()
{ {
NotificationManager()->Register(this); NotificationManager()->Register(this);

View File

@ -956,7 +956,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param; LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param;
assert(m_buildState); assert(m_buildState);
if (param->m_unk0x28) { if (param->m_enabledChild) {
switch (param->m_clickedObjectId) { switch (param->m_clickedObjectId) {
// The enum values are all identical between CopterScript, DunecarScript, JetskiScript, and RacecarScript // The enum values are all identical between CopterScript, DunecarScript, JetskiScript, and RacecarScript
case CopterScript::c_Info_Ctl: case CopterScript::c_Info_Ctl:
@ -1012,7 +1012,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
case CopterScript::c_Platform_Ctl: case CopterScript::c_Platform_Ctl:
FUN_10024f50(); FUN_10024f50();
m_unk0xf8 = c_unknown8; m_unk0xf8 = c_unknown8;
m_unk0xfc = param->m_unk0x28; m_unk0xfc = param->m_enabledChild;
result = 1; result = 1;
break; break;
default: default:
@ -1054,7 +1054,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param; LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param;
assert(m_buildState); assert(m_buildState);
if (param->m_unk0x28) { if (param->m_enabledChild) {
switch (param->m_clickedObjectId) { switch (param->m_clickedObjectId) {
case CopterScript::c_Info_Ctl: case CopterScript::c_Info_Ctl:
m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_selected); m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_selected);
@ -1116,7 +1116,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
case CopterScript::c_Platform_Ctl: case CopterScript::c_Platform_Ctl:
FUN_10024f50(); FUN_10024f50();
m_unk0xf8 = c_unknown8; m_unk0xf8 = c_unknown8;
m_unk0xfc = param->m_unk0x28; m_unk0xfc = param->m_enabledChild;
result = 1; result = 1;
break; break;
default: default:
@ -1233,7 +1233,7 @@ undefined4 LegoCarBuild::FUN_10024c20(MxNotificationParam* p_param)
jukeboxScript = JukeboxScript::c_RaceCarBuild_Music; jukeboxScript = JukeboxScript::c_RaceCarBuild_Music;
} }
m_unk0x338 = SoundManager()->FUN_100aebd0(*g_jukeboxScript, jukeboxScript); m_unk0x338 = SoundManager()->FindPresenter(*g_jukeboxScript, jukeboxScript);
if (m_unk0x338) { if (m_unk0x338) {
BackgroundAudioManager()->SetPendingPresenter(m_unk0x338, 5, MxPresenter::e_repeating); BackgroundAudioManager()->SetPendingPresenter(m_unk0x338, 5, MxPresenter::e_repeating);

View File

@ -11,7 +11,6 @@
#include "legoentitylist.h" #include "legoentitylist.h"
#include "legoextraactor.h" #include "legoextraactor.h"
#include "legogamestate.h" #include "legogamestate.h"
#include "legolocomotionanimpresenter.h"
#include "legomain.h" #include "legomain.h"
#include "legonavcontroller.h" #include "legonavcontroller.h"
#include "legoroilist.h" #include "legoroilist.h"
@ -20,6 +19,7 @@
#include "legoworld.h" #include "legoworld.h"
#include "misc.h" #include "misc.h"
#include "mxbackgroundaudiomanager.h" #include "mxbackgroundaudiomanager.h"
#include "mxdebug.h"
#include "mxmisc.h" #include "mxmisc.h"
#include "mxnotificationmanager.h" #include "mxnotificationmanager.h"
#include "mxticklemanager.h" #include "mxticklemanager.h"
@ -1021,7 +1021,7 @@ MxResult LegoAnimationManager::FUN_100605e0(
action.SetUnknown24(-1); action.SetUnknown24(-1);
action.AppendExtra(strlen(buf) + 1, buf); action.AppendExtra(strlen(buf) + 1, buf);
if (StartActionIfUnknown0x13c(action) == SUCCESS) { if (StartActionIfInitialized(action) == SUCCESS) {
BackgroundAudioManager()->LowerVolume(); BackgroundAudioManager()->LowerVolume();
tranInfo->m_flags |= LegoTranInfo::c_bit2; tranInfo->m_flags |= LegoTranInfo::c_bit2;
animInfo.m_unk0x22++; animInfo.m_unk0x22++;
@ -1088,7 +1088,7 @@ MxResult LegoAnimationManager::FUN_100609f0(MxU32 p_objectId, MxMatrix* p_matrix
action.SetUnknown24(-1); action.SetUnknown24(-1);
action.AppendExtra(strlen(buf) + 1, buf); action.AppendExtra(strlen(buf) + 1, buf);
if (StartActionIfUnknown0x13c(action) == SUCCESS) { if (StartActionIfInitialized(action) == SUCCESS) {
BackgroundAudioManager()->LowerVolume(); BackgroundAudioManager()->LowerVolume();
info->m_flags |= LegoTranInfo::c_bit2; info->m_flags |= LegoTranInfo::c_bit2;
m_animRunning = TRUE; m_animRunning = TRUE;
@ -1131,7 +1131,7 @@ MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEnt
} }
} }
if (LegoOmni::GetInstance()->StartActionIfUnknown0x13c(p_dsAction) == SUCCESS) { if (LegoOmni::GetInstance()->StartActionIfInitialized(p_dsAction) == SUCCESS) {
result = SUCCESS; result = SUCCESS;
} }
@ -1155,7 +1155,7 @@ MxResult LegoAnimationManager::FUN_10060dc0(
MxResult result = FAILURE; MxResult result = FAILURE;
MxBool found = FALSE; MxBool found = FALSE;
if (!Lego()->m_unk0x13c) { if (!Lego()->m_initialized) {
return SUCCESS; return SUCCESS;
} }
@ -1192,7 +1192,7 @@ MxResult LegoAnimationManager::FUN_10060dc0(
// FUNCTION: BETA10 0x1004206c // FUNCTION: BETA10 0x1004206c
void LegoAnimationManager::CameraTriggerFire(LegoPathActor* p_actor, MxBool, MxU32 p_location, MxBool p_bool) void LegoAnimationManager::CameraTriggerFire(LegoPathActor* p_actor, MxBool, MxU32 p_location, MxBool p_bool)
{ {
if (Lego()->m_unk0x13c && m_enableCamAnims && !m_animRunning) { if (Lego()->m_initialized && m_enableCamAnims && !m_animRunning) {
LegoLocation* location = LegoNavController::GetLocation(p_location); LegoLocation* location = LegoNavController::GetLocation(p_location);
if (location != NULL) { if (location != NULL) {
@ -1231,12 +1231,10 @@ void LegoAnimationManager::CameraTriggerFire(LegoPathActor* p_actor, MxBool, MxU
} }
} }
// FUNCTION: LEGO1 0x10061010 #ifdef BETA10
// FUNCTION: BETA10 0x100422cc // FUNCTION: BETA10 0x100422cc
void LegoAnimationManager::FUN_10061010(MxBool p_und) void LegoAnimationManager::FUN_10061010(MxBool p_und)
{ {
MxBool unk0x39 = FALSE;
FUN_10064b50(-1); FUN_10064b50(-1);
if (m_tranInfoList != NULL) { if (m_tranInfoList != NULL) {
@ -1244,17 +1242,47 @@ void LegoAnimationManager::FUN_10061010(MxBool p_und)
LegoTranInfo* tranInfo; LegoTranInfo* tranInfo;
while (cursor.Next(tranInfo)) { while (cursor.Next(tranInfo)) {
if (tranInfo->m_presenter != NULL) { if (tranInfo->m_unk0x14 && tranInfo->m_location != -1) {
// TODO: Match MxTrace("Releasing user from %d\n", tranInfo->m_objectId);
MxU32 flags = tranInfo->m_flags;
if (tranInfo->m_presenter != NULL) {
tranInfo->m_presenter->FUN_1004b8c0();
}
tranInfo->m_unk0x14 = FALSE;
}
else {
MxTrace("Stopping %d\n", tranInfo->m_objectId);
if (tranInfo->m_presenter != NULL) {
tranInfo->m_presenter->FUN_1004b840();
}
}
}
}
m_animRunning = FALSE;
m_unk0x404 = Timer()->GetTime();
}
#else
// FUNCTION: LEGO1 0x10061010
void LegoAnimationManager::FUN_10061010(MxBool p_und)
{
MxBool animRunning = FALSE;
FUN_10064b50(-1);
if (m_tranInfoList != NULL) {
LegoTranInfoListCursor cursor(m_tranInfoList);
LegoTranInfo* tranInfo;
while (cursor.Next(tranInfo)) {
if (tranInfo->m_presenter) {
// LINE: LEGO1 0x100610e6
if (tranInfo->m_unk0x14 && tranInfo->m_location != -1 && p_und) { if (tranInfo->m_unk0x14 && tranInfo->m_location != -1 && p_und) {
LegoAnim* anim; if (tranInfo->m_presenter->GetPresenter() &&
tranInfo->m_presenter->GetPresenter()->GetAnimation() &&
if (tranInfo->m_presenter->GetPresenter() != NULL && tranInfo->m_presenter->GetPresenter()->GetAnimation()->GetCamAnim()) {
(anim = tranInfo->m_presenter->GetPresenter()->GetAnimation()) != NULL && if (tranInfo->m_flags & LegoTranInfo::c_bit2) {
anim->GetCamAnim() != NULL) {
if (flags & LegoTranInfo::c_bit2) {
BackgroundAudioManager()->RaiseVolume(); BackgroundAudioManager()->RaiseVolume();
tranInfo->m_flags &= ~LegoTranInfo::c_bit2; tranInfo->m_flags &= ~LegoTranInfo::c_bit2;
} }
@ -1263,37 +1291,43 @@ void LegoAnimationManager::FUN_10061010(MxBool p_und)
tranInfo->m_unk0x14 = FALSE; tranInfo->m_unk0x14 = FALSE;
} }
else { else {
MxTrace("Releasing user from %d\n", tranInfo->m_objectId);
// LINE: LEGO1 0x10061137
tranInfo->m_presenter->FUN_1004b8c0(); tranInfo->m_presenter->FUN_1004b8c0();
animRunning = TRUE;
tranInfo->m_unk0x14 = FALSE; tranInfo->m_unk0x14 = FALSE;
unk0x39 = TRUE;
} }
} }
else { else {
if (flags & LegoTranInfo::c_bit2) { if (tranInfo->m_flags & LegoTranInfo::c_bit2) {
// LINE: LEGO1 0x10061150
BackgroundAudioManager()->RaiseVolume(); BackgroundAudioManager()->RaiseVolume();
tranInfo->m_flags &= ~LegoTranInfo::c_bit2; tranInfo->m_flags &= ~LegoTranInfo::c_bit2;
} }
MxTrace("Stopping %d\n", tranInfo->m_objectId);
tranInfo->m_presenter->FUN_1004b840(); tranInfo->m_presenter->FUN_1004b840();
} }
} }
else { else {
if (m_tranInfoList2 != NULL) { if (m_tranInfoList2 != NULL) {
LegoTranInfoListCursor cursor(m_tranInfoList2); LegoTranInfoListCursor cursor(m_tranInfoList2);
if (!cursor.Find(tranInfo)) { if (!cursor.Find(tranInfo)) {
// TODO: For some reason, the embedded `MxListEntry` constructor is not inlined.
// This may be the key for getting this function to match correctly.
m_tranInfoList2->Append(tranInfo); m_tranInfoList2->Append(tranInfo);
} }
} }
unk0x39 = TRUE; animRunning = TRUE;
} }
} }
} }
m_animRunning = unk0x39; m_animRunning = animRunning;
m_unk0x404 = Timer()->GetTime(); m_unk0x404 = Timer()->GetTime();
} }
#endif
// FUNCTION: LEGO1 0x10061530 // FUNCTION: LEGO1 0x10061530
void LegoAnimationManager::FUN_10061530() void LegoAnimationManager::FUN_10061530()
@ -2784,7 +2818,11 @@ MxResult LegoAnimationManager::FUN_10064880(const char* p_name, MxS32 p_unk0x0c,
// FUNCTION: BETA10 0x10045daf // FUNCTION: BETA10 0x10045daf
void LegoAnimationManager::FUN_100648f0(LegoTranInfo* p_tranInfo, MxLong p_unk0x404) void LegoAnimationManager::FUN_100648f0(LegoTranInfo* p_tranInfo, MxLong p_unk0x404)
{ {
if (m_unk0x402 && p_tranInfo->m_unk0x14) { if (
#ifndef BETA10
m_unk0x402 &&
#endif
p_tranInfo->m_unk0x14) {
p_tranInfo->m_flags |= LegoTranInfo::c_bit1; p_tranInfo->m_flags |= LegoTranInfo::c_bit1;
m_unk0x430 = TRUE; m_unk0x430 = TRUE;
m_unk0x42c = p_tranInfo; m_unk0x42c = p_tranInfo;
@ -2805,11 +2843,13 @@ void LegoAnimationManager::FUN_100648f0(LegoTranInfo* p_tranInfo, MxLong p_unk0x
if (location != NULL) { if (location != NULL) {
CalcLocalTransform(location->m_position, location->m_direction, location->m_up, m_unk0x484); CalcLocalTransform(location->m_position, location->m_direction, location->m_up, m_unk0x484);
m_unk0x4cc.SetStartEnd(m_unk0x43c, m_unk0x484); m_unk0x4cc.SetStartEnd(m_unk0x43c, m_unk0x484);
#ifndef BETA10
m_unk0x4cc.NormalizeDirection(); m_unk0x4cc.NormalizeDirection();
} }
else { else {
p_tranInfo->m_flags &= ~LegoTranInfo::c_bit1; p_tranInfo->m_flags &= ~LegoTranInfo::c_bit1;
m_unk0x430 = FALSE; m_unk0x430 = FALSE;
#endif
} }
Mx3DPointFloat vec; Mx3DPointFloat vec;

View File

@ -425,6 +425,21 @@ MxBool LegoAnimMMPresenter::FUN_1004b6b0(MxLong p_time)
// FUNCTION: BETA10 0x1004ce18 // FUNCTION: BETA10 0x1004ce18
MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time) MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time)
{ {
#ifdef BETA10
switch (m_unk0x58) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
}
#endif
LegoROI* viewROI = VideoManager()->GetViewROI(); LegoROI* viewROI = VideoManager()->GetViewROI();
LegoPathActor* actor = UserActor(); LegoPathActor* actor = UserActor();
@ -455,9 +470,13 @@ MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time)
m_world->PlaceActor(actor); m_world->PlaceActor(actor);
} }
#ifdef BETA10
actor->VTable0xa8();
#else
if (m_tranInfo->m_unk0x29) { if (m_tranInfo->m_unk0x29) {
actor->VTable0xa8(); actor->VTable0xa8();
} }
#endif
} }
actor->SetActorState(LegoPathActor::c_initial); actor->SetActorState(LegoPathActor::c_initial);
@ -491,9 +510,11 @@ void LegoAnimMMPresenter::FUN_1004b840()
FUN_1004b6d0(0); FUN_1004b6d0(0);
EndAction(); EndAction();
#ifndef BETA10
if (action != NULL) { if (action != NULL) {
Streamer()->FUN_100b98f0(action); Streamer()->FUN_100b98f0(action);
} }
#endif
} }
// FUNCTION: LEGO1 0x1004b8b0 // FUNCTION: LEGO1 0x1004b8b0

View File

@ -47,6 +47,7 @@ MxU8 g_buildingInfoDownshift[16] = {
}; };
// GLOBAL: LEGO1 0x100f3478 // GLOBAL: LEGO1 0x100f3478
// GLOBAL: BETA10 0x101e4d78
LegoBuildingInfo g_buildingInfoInit[16] = { LegoBuildingInfo g_buildingInfoInit[16] = {
{ {
NULL, "infocen", NULL, "infocen",
@ -236,8 +237,11 @@ void LegoBuildingManager::configureLegoBuildingManager(MxS32 p_buildingManagerCo
} }
// FUNCTION: LEGO1 0x1002f8c0 // FUNCTION: LEGO1 0x1002f8c0
// FUNCTION: BETA10 0x10063a30
LegoBuildingManager::LegoBuildingManager() LegoBuildingManager::LegoBuildingManager()
{ {
// Note that Init() is inlined in BETA10 and the class did not inherit from MxCore,
// so the BETA10 match is much better on Init().
Init(); Init();
} }
@ -247,6 +251,7 @@ LegoBuildingManager::~LegoBuildingManager()
delete[] g_customizeAnimFile; delete[] g_customizeAnimFile;
} }
// // FUNCTION: BETA10 0x10063a30 -- see the constructor
// FUNCTION: LEGO1 0x1002f9d0 // FUNCTION: LEGO1 0x1002f9d0
void LegoBuildingManager::Init() void LegoBuildingManager::Init()
{ {

View File

@ -1092,6 +1092,7 @@ LegoROI* LegoCharacterManager::FUN_10085a80(const char* p_name, const char* p_lo
} }
// FUNCTION: LEGO1 0x10085aa0 // FUNCTION: LEGO1 0x10085aa0
// FUNCTION: BETA10 0x1007703d
CustomizeAnimFileVariable::CustomizeAnimFileVariable(const char* p_key) CustomizeAnimFileVariable::CustomizeAnimFileVariable(const char* p_key)
{ {
m_key = p_key; m_key = p_key;
@ -1099,6 +1100,7 @@ CustomizeAnimFileVariable::CustomizeAnimFileVariable(const char* p_key)
} }
// FUNCTION: LEGO1 0x10085b50 // FUNCTION: LEGO1 0x10085b50
// FUNCTION: BETA10 0x100770c8
void CustomizeAnimFileVariable::SetValue(const char* p_value) void CustomizeAnimFileVariable::SetValue(const char* p_value)
{ {
// STRING: LEGO1 0x100fc4f4 // STRING: LEGO1 0x100fc4f4

View File

@ -1179,28 +1179,28 @@ void LegoGameState::Init()
Helicopter* copter = (Helicopter*) isle->Find(*g_copterScript, CopterScript::c_Helicopter_Actor); Helicopter* copter = (Helicopter*) isle->Find(*g_copterScript, CopterScript::c_Helicopter_Actor);
if (copter) { if (copter) {
isle->RemoveActor(copter); isle->RemoveActor(copter);
isle->VTable0x6c(copter); isle->RemoveVehicle(copter);
delete copter; delete copter;
} }
DuneBuggy* dunebuggy = (DuneBuggy*) isle->Find(*g_dunecarScript, DunecarScript::c_DuneBugy_Actor); DuneBuggy* dunebuggy = (DuneBuggy*) isle->Find(*g_dunecarScript, DunecarScript::c_DuneBugy_Actor);
if (dunebuggy) { if (dunebuggy) {
isle->RemoveActor(dunebuggy); isle->RemoveActor(dunebuggy);
isle->VTable0x6c(dunebuggy); isle->RemoveVehicle(dunebuggy);
delete dunebuggy; delete dunebuggy;
} }
Jetski* jetski = (Jetski*) isle->Find(*g_jetskiScript, JetskiScript::c_Jetski_Actor); Jetski* jetski = (Jetski*) isle->Find(*g_jetskiScript, JetskiScript::c_Jetski_Actor);
if (jetski) { if (jetski) {
isle->RemoveActor(jetski); isle->RemoveActor(jetski);
isle->VTable0x6c(jetski); isle->RemoveVehicle(jetski);
delete jetski; delete jetski;
} }
RaceCar* racecar = (RaceCar*) isle->Find(*g_racecarScript, RacecarScript::c_RaceCar_Actor); RaceCar* racecar = (RaceCar*) isle->Find(*g_racecarScript, RacecarScript::c_RaceCar_Actor);
if (racecar) { if (racecar) {
isle->RemoveActor(racecar); isle->RemoveActor(racecar);
isle->VTable0x6c(racecar); isle->RemoveVehicle(racecar);
delete racecar; delete racecar;
} }
} }
@ -1349,6 +1349,11 @@ void LegoBackgroundColor::SetLightColor()
SetLightColor(convertedR, convertedG, convertedB); SetLightColor(convertedR, convertedG, convertedB);
} }
// FUNCTION: BETA10 0x10086a87
LegoFullScreenMovie::LegoFullScreenMovie()
{
}
// FUNCTION: LEGO1 0x1003c500 // FUNCTION: LEGO1 0x1003c500
// FUNCTION: BETA10 0x10086af6 // FUNCTION: BETA10 0x10086af6
LegoFullScreenMovie::LegoFullScreenMovie(const char* p_key, const char* p_value) LegoFullScreenMovie::LegoFullScreenMovie(const char* p_key, const char* p_value)

View File

@ -10,7 +10,7 @@
#include "legoentity.h" #include "legoentity.h"
#include "legopathactor.h" #include "legopathactor.h"
// The below header inclusions should be sound. // The below header inclusions should be sound.
#include "legoloopinganimpresenter.h" #include "legoanimpresenter.h"
#include "mxcompositemediapresenter.h" #include "mxcompositemediapresenter.h"
#include "legoactorpresenter.h" #include "legoactorpresenter.h"
#include "legomodelpresenter.h" #include "legomodelpresenter.h"
@ -71,10 +71,7 @@
#include "legoentity.h" #include "legoentity.h"
#include "legoentitypresenter.h" #include "legoentitypresenter.h"
#include "legoflctexturepresenter.h" #include "legoflctexturepresenter.h"
#include "legohideanimpresenter.h"
#include "legoloadcachesoundpresenter.h" #include "legoloadcachesoundpresenter.h"
#include "legolocomotionanimpresenter.h"
#include "legoloopinganimpresenter.h"
#include "legometerpresenter.h" #include "legometerpresenter.h"
#include "legomodelpresenter.h" #include "legomodelpresenter.h"
#include "legopalettepresenter.h" #include "legopalettepresenter.h"

View File

@ -60,8 +60,11 @@ char* LegoPlantManager::g_customizeAnimFile = NULL;
LegoPlantInfo g_plantInfo[81]; LegoPlantInfo g_plantInfo[81];
// FUNCTION: LEGO1 0x10026220 // FUNCTION: LEGO1 0x10026220
// FUNCTION: BETA10 0x100c4f90
LegoPlantManager::LegoPlantManager() LegoPlantManager::LegoPlantManager()
{ {
// Note that Init() is inlined in BETA10 and the class did not inherit from MxCore,
// so the BETA10 match is much better on Init().
Init(); Init();
} }
@ -72,12 +75,10 @@ LegoPlantManager::~LegoPlantManager()
delete[] g_customizeAnimFile; delete[] g_customizeAnimFile;
} }
// // FUNCTION: BETA10 0x100c4f90 -- see the constructor
// FUNCTION: LEGO1 0x10026330 // FUNCTION: LEGO1 0x10026330
// FUNCTION: BETA10 0x100c4f90
void LegoPlantManager::Init() void LegoPlantManager::Init()
{ {
// In BETA10 this appears to be LegoPlantManager::LegoPlantManager()
for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) { for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
g_plantInfo[i] = g_plantInfoInit[i]; g_plantInfo[i] = g_plantInfoInit[i];
} }

View File

@ -784,9 +784,10 @@ void LoadFromNamedTexture(LegoNamedTexture* p_namedTexture)
} }
} }
void HitActorEvent() void EmitGameEvent(GameEvent p_event)
{ {
SDL_Event event; SDL_Event event;
event.user.type = g_legoSdlEvents.m_hitActor; event.user.type = g_legoSdlEvents.m_gameEvent;
event.user.code = p_event;
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }

View File

@ -6,6 +6,7 @@
#include "legonavcontroller.h" #include "legonavcontroller.h"
#include "legovideomanager.h" #include "legovideomanager.h"
#include "misc.h" #include "misc.h"
#include "mxdebug.h"
#include "roi/legoroi.h" #include "roi/legoroi.h"
#include <SDL3/SDL_stdinc.h> #include <SDL3/SDL_stdinc.h>
@ -103,6 +104,10 @@ const char* g_nick = "Nick";
// STRING: LEGO1 0x100f39e0 // STRING: LEGO1 0x100f39e0
const char* g_laura = "Laura"; const char* g_laura = "Laura";
// GLOBAL: BETA10 0x101f6ce4
// STRING: BETA10 0x101f6d54
const char* g_varDEBUG = "DEBUG";
// FUNCTION: LEGO1 0x10037d00 // FUNCTION: LEGO1 0x10037d00
// FUNCTION: BETA10 0x100d5620 // FUNCTION: BETA10 0x100d5620
void VisibilityVariable::SetValue(const char* p_value) void VisibilityVariable::SetValue(const char* p_value)
@ -132,6 +137,7 @@ void VisibilityVariable::SetValue(const char* p_value)
} }
// FUNCTION: LEGO1 0x10037d80 // FUNCTION: LEGO1 0x10037d80
// FUNCTION: BETA10 0x100d56ee
void CameraLocationVariable::SetValue(const char* p_value) void CameraLocationVariable::SetValue(const char* p_value)
{ {
char buffer[256]; char buffer[256];
@ -139,22 +145,25 @@ void CameraLocationVariable::SetValue(const char* p_value)
strcpy(buffer, p_value); strcpy(buffer, p_value);
char* location = strtok(buffer, ","); char* token = strtok(buffer, ",");
NavController()->UpdateLocation(location); assert(token);
NavController()->UpdateLocation(token);
location = strtok(NULL, ","); token = strtok(NULL, ",");
if (location) { if (token) {
MxFloat pov = (MxFloat) atof(location); MxFloat pov = (MxFloat) atof(token);
VideoManager()->Get3DManager()->SetFrustrum(pov, 0.1f, 250.0f); VideoManager()->Get3DManager()->SetFrustrum(pov, 0.1f, 250.0f);
} }
} }
// FUNCTION: LEGO1 0x10037e30 // FUNCTION: LEGO1 0x10037e30
// FUNCTION: BETA10 0x100d57e2
void CursorVariable::SetValue(const char* p_value) void CursorVariable::SetValue(const char* p_value)
{ {
} }
// FUNCTION: LEGO1 0x10037e40 // FUNCTION: LEGO1 0x10037e40
// FUNCTION: BETA10 0x100d57fa
void WhoAmIVariable::SetValue(const char* p_value) void WhoAmIVariable::SetValue(const char* p_value)
{ {
MxVariable::SetValue(p_value); MxVariable::SetValue(p_value);
@ -175,3 +184,10 @@ void WhoAmIVariable::SetValue(const char* p_value)
GameState()->SetActorId(LegoActor::c_laura); GameState()->SetActorId(LegoActor::c_laura);
} }
} }
// FUNCTION: BETA10 0x100d58fa
void DebugVariable::SetValue(const char* p_value)
{
MxVariable::SetValue(p_value);
MxTrace("%s\n", p_value);
}

View File

@ -127,8 +127,10 @@ LegoBuildingManager* BuildingManager()
} }
// FUNCTION: LEGO1 0x10015800 // FUNCTION: LEGO1 0x10015800
// FUNCTION: BETA10 0x100e4bb7
LegoTextureContainer* TextureContainer() LegoTextureContainer* TextureContainer()
{ {
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->GetTextureContainer(); return LegoOmni::GetInstance()->GetTextureContainer();
} }
@ -172,9 +174,9 @@ void SetUserActor(LegoPathActor* p_userActor)
// FUNCTION: LEGO1 0x10015890 // FUNCTION: LEGO1 0x10015890
// FUNCTION: BETA10 0x100e4d80 // FUNCTION: BETA10 0x100e4d80
MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) MxResult StartActionIfInitialized(MxDSAction& p_dsAction)
{ {
return LegoOmni::GetInstance()->StartActionIfUnknown0x13c(p_dsAction); return LegoOmni::GetInstance()->StartActionIfInitialized(p_dsAction);
} }
// FUNCTION: LEGO1 0x100158b0 // FUNCTION: LEGO1 0x100158b0

View File

@ -27,6 +27,7 @@ MxCompositeMediaPresenter::~MxCompositeMediaPresenter()
} }
// FUNCTION: LEGO1 0x10074090 // FUNCTION: LEGO1 0x10074090
// FUNCTION: BETA10 0x100e9d37
MxResult MxCompositeMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) MxResult MxCompositeMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action)
{ {
AUTOLOCK(m_criticalSection); AUTOLOCK(m_criticalSection);

View File

@ -80,17 +80,14 @@ MxBool MxControlPresenter::CheckButtonDown(MxS32 p_x, MxS32 p_y, MxPresenter* p_
{ {
assert(p_presenter); assert(p_presenter);
MxVideoPresenter* presenter = dynamic_cast<MxVideoPresenter*>(p_presenter); MxVideoPresenter* presenter = dynamic_cast<MxVideoPresenter*>(p_presenter);
if (!presenter) { assert(presenter);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Invalid presenter");
return FALSE;
}
if (m_style == e_map) { if (m_style == e_map) {
MxStillPresenter* map = (MxStillPresenter*) m_list.front(); MxStillPresenter* map = (MxStillPresenter*) m_list.front();
assert(map && map->IsA("MxStillPresenter")); assert(map && map->IsA("MxStillPresenter"));
if (presenter == map || map->GetDisplayZ() < presenter->GetDisplayZ()) { if (presenter == map || map->GetDisplayZ() < presenter->GetDisplayZ()) {
if (map->VTable0x7c()) { if (map->HasFrameBitmapOrAlpha()) {
MxRect32 rect(0, 0, map->GetWidth() - 1, map->GetHeight() - 1); MxRect32 rect(0, 0, map->GetWidth() - 1, map->GetHeight() - 1);
rect += map->GetLocation(); rect += map->GetLocation();
@ -160,7 +157,7 @@ MxBool MxControlPresenter::Notify(LegoControlManagerNotificationParam* p_param,
p_param->SetClickedAtom(m_action->GetAtomId().GetInternal()); p_param->SetClickedAtom(m_action->GetAtomId().GetInternal());
UpdateEnabledChild(0); UpdateEnabledChild(0);
p_param->SetNotification(c_notificationControl); p_param->SetNotification(c_notificationControl);
p_param->SetUnknown0x28(m_enabledChild); p_param->SetEnabledChild(m_enabledChild);
return TRUE; return TRUE;
} }
break; break;
@ -170,7 +167,7 @@ MxBool MxControlPresenter::Notify(LegoControlManagerNotificationParam* p_param,
p_param->SetClickedAtom(m_action->GetAtomId().GetInternal()); p_param->SetClickedAtom(m_action->GetAtomId().GetInternal());
UpdateEnabledChild(m_stateOrCellIndex); UpdateEnabledChild(m_stateOrCellIndex);
p_param->SetNotification(c_notificationControl); p_param->SetNotification(c_notificationControl);
p_param->SetUnknown0x28(m_enabledChild); p_param->SetEnabledChild(m_enabledChild);
return TRUE; return TRUE;
} }
break; break;

View File

@ -22,6 +22,7 @@ MxTransitionManager::TransitionType g_transitionManagerConfig = MxTransitionMana
RECT g_fullScreenRect = {0, 0, 640, 480}; RECT g_fullScreenRect = {0, 0, 640, 480};
// FUNCTION: LEGO1 0x1004b8d0 // FUNCTION: LEGO1 0x1004b8d0
// FUNCTION: BETA10 0x100ec2c0
MxTransitionManager::MxTransitionManager() MxTransitionManager::MxTransitionManager()
{ {
m_animationTimer = 0; m_animationTimer = 0;

View File

@ -14,6 +14,7 @@ DECOMP_SIZE_ASSERT(LegoControlManagerNotificationParam, 0x2c)
DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x20) DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x20)
// FUNCTION: LEGO1 0x10028520 // FUNCTION: LEGO1 0x10028520
// STUB: BETA10 0x1008ae50
LegoControlManager::LegoControlManager() LegoControlManager::LegoControlManager()
{ {
m_presenterList = NULL; m_presenterList = NULL;

View File

@ -124,28 +124,28 @@ void LegoCameraController::OnMouseMove(MxU8 p_modifier, MxPoint32 p_point)
// FUNCTION: LEGO1 0x10012260 // FUNCTION: LEGO1 0x10012260
void LegoCameraController::SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up) void LegoCameraController::SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up)
{ {
CalcLocalTransform(p_at, p_dir, p_up, m_matrix1); CalcLocalTransform(p_at, p_dir, p_up, m_currentTransform);
m_matrix2 = m_matrix1; m_originalTransform = m_currentTransform;
} }
// FUNCTION: LEGO1 0x10012290 // FUNCTION: LEGO1 0x10012290
// FUNCTION: BETA10 0x10068c34 // FUNCTION: BETA10 0x10068c34
void LegoCameraController::FUN_10012290(float p_angle) void LegoCameraController::RotateZ(float p_angle)
{ {
m_matrix1 = m_matrix2; m_currentTransform = m_originalTransform;
m_matrix1.RotateZ(p_angle); m_currentTransform.RotateZ(p_angle);
} }
// FUNCTION: LEGO1 0x10012320 // FUNCTION: LEGO1 0x10012320
// FUNCTION: BETA10 0x10068c73 // FUNCTION: BETA10 0x10068c73
void LegoCameraController::FUN_10012320(float p_angle) void LegoCameraController::RotateY(float p_angle)
{ {
m_matrix1 = m_matrix2; m_currentTransform = m_originalTransform;
m_matrix1.RotateY(p_angle); m_currentTransform.RotateY(p_angle);
} }
// FUNCTION: LEGO1 0x100123b0 // FUNCTION: LEGO1 0x100123b0
MxResult LegoCameraController::FUN_100123b0(Matrix4& p_matrix) MxResult LegoCameraController::GetPointOfView(Matrix4& p_matrix)
{ {
if (m_lego3DView) { if (m_lego3DView) {
ViewROI* pov = m_lego3DView->GetPointOfView(); ViewROI* pov = m_lego3DView->GetPointOfView();
@ -160,7 +160,7 @@ MxResult LegoCameraController::FUN_100123b0(Matrix4& p_matrix)
// FUNCTION: LEGO1 0x100123e0 // FUNCTION: LEGO1 0x100123e0
// FUNCTION: BETA10 0x10068cb2 // FUNCTION: BETA10 0x10068cb2
void LegoCameraController::FUN_100123e0(const Matrix4& p_transform, MxU32 p_und) void LegoCameraController::TransformPointOfView(const Matrix4& p_transform, MxU32 p_multiply)
{ {
if (m_lego3DView != NULL) { if (m_lego3DView != NULL) {
ViewROI* pov = m_lego3DView->GetPointOfView(); ViewROI* pov = m_lego3DView->GetPointOfView();
@ -168,14 +168,14 @@ void LegoCameraController::FUN_100123e0(const Matrix4& p_transform, MxU32 p_und)
if (pov != NULL) { if (pov != NULL) {
MxMatrix mat; MxMatrix mat;
if (p_und) { if (p_multiply) {
MXM4(mat, m_matrix1, p_transform); MXM4(mat, m_currentTransform, p_transform);
} }
else { else {
mat = p_transform; mat = p_transform;
} }
((TimeROI*) pov)->FUN_100a9b40(mat, Timer()->GetTime()); ((TimeROI*) pov)->CalculateWorldVelocity(mat, Timer()->GetTime());
pov->WrappedSetLocal2WorldWithWorldDataUpdate(mat); pov->WrappedSetLocal2WorldWithWorldDataUpdate(mat);
m_lego3DView->Moved(*pov); m_lego3DView->Moved(*pov);

View File

@ -197,7 +197,7 @@ void LegoEntity::FUN_10010c30()
LegoWorld* world = CurrentWorld(); LegoWorld* world = CurrentWorld();
if (m_cameraFlag && world && world->GetCameraController() && m_roi) { if (m_cameraFlag && world && world->GetCameraController() && m_roi) {
world->GetCameraController()->FUN_100123e0(m_roi->GetLocal2World(), 1); world->GetCameraController()->TransformPointOfView(m_roi->GetLocal2World(), 1);
} }
} }

View File

@ -555,7 +555,7 @@ MxResult LegoNavController::ProcessJoystickInput(MxBool& p_und)
LegoWorld* world = CurrentWorld(); LegoWorld* world = CurrentWorld();
if (world && world->GetCameraController()) { if (world && world->GetCameraController()) {
world->GetCameraController()->FUN_10012320(DTOR(povPosition)); world->GetCameraController()->RotateY(DTOR(povPosition));
p_und = TRUE; p_und = TRUE;
} }
} }
@ -672,10 +672,10 @@ MxLong LegoNavController::Notify(MxParam& p_param)
InfocenterState* state = (InfocenterState*) GameState()->GetState("InfocenterState"); InfocenterState* state = (InfocenterState*) GameState()->GetState("InfocenterState");
assert(state); assert(state);
if (state != NULL && state->m_unk0x74 != 8 && currentWorld->Escape()) { if (state != NULL && state->m_state != InfocenterState::e_exitQueried && currentWorld->Escape()) {
BackgroundAudioManager()->Stop(); BackgroundAudioManager()->Stop();
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
state->m_unk0x74 = 8; state->m_state = InfocenterState::e_exitQueried;
} }
} }
break; break;
@ -902,7 +902,7 @@ MxLong LegoNavController::Notify(MxParam& p_param)
break; break;
case SDLK_A: case SDLK_A:
if (g_animationCalcStep == 1) { if (g_animationCalcStep == 1) {
Lego()->m_unk0x13c = TRUE; Lego()->m_initialized = TRUE;
AnimationManager()->FUN_10060570(TRUE); AnimationManager()->FUN_10060570(TRUE);
g_animationCalcStep = 0; g_animationCalcStep = 0;
} }

View File

@ -153,7 +153,7 @@ MxResult LegoPointOfViewController::Tickle()
MxMatrix mat; MxMatrix mat;
CalcLocalTransform(newPos, newDir, pov->GetWorldUp(), mat); CalcLocalTransform(newPos, newDir, pov->GetWorldUp(), mat);
((TimeROI*) pov)->FUN_100a9b40(mat, Timer()->GetTime()); ((TimeROI*) pov)->CalculateWorldVelocity(mat, Timer()->GetTime());
pov->WrappedSetLocal2WorldWithWorldDataUpdate(mat); pov->WrappedSetLocal2WorldWithWorldDataUpdate(mat);
m_lego3DView->Moved(*pov); m_lego3DView->Moved(*pov);

View File

@ -9,7 +9,6 @@
#include "legocontrolmanager.h" #include "legocontrolmanager.h"
#include "legogamestate.h" #include "legogamestate.h"
#include "legoinputmanager.h" #include "legoinputmanager.h"
#include "legolocomotionanimpresenter.h"
#include "legonavcontroller.h" #include "legonavcontroller.h"
#include "legoplantmanager.h" #include "legoplantmanager.h"
#include "legosoundmanager.h" #include "legosoundmanager.h"
@ -288,6 +287,7 @@ MxResult LegoWorld::PlaceActor(
} }
// FUNCTION: LEGO1 0x1001fa70 // FUNCTION: LEGO1 0x1001fa70
// FUNCTION: BETA10 0x100da328
MxResult LegoWorld::PlaceActor(LegoPathActor* p_actor) MxResult LegoWorld::PlaceActor(LegoPathActor* p_actor)
{ {
LegoPathControllerListCursor cursor(&m_pathControllerList); LegoPathControllerListCursor cursor(&m_pathControllerList);
@ -303,6 +303,7 @@ MxResult LegoWorld::PlaceActor(LegoPathActor* p_actor)
} }
// FUNCTION: LEGO1 0x1001fb70 // FUNCTION: LEGO1 0x1001fb70
// FUNCTION: BETA10 0x100da3f1
MxResult LegoWorld::PlaceActor( MxResult LegoWorld::PlaceActor(
LegoPathActor* p_actor, LegoPathActor* p_actor,
LegoAnimPresenter* p_presenter, LegoAnimPresenter* p_presenter,

View File

@ -260,8 +260,12 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world)
ModelDbPart* part; ModelDbPart* part;
while (cursor.Next(part)) { while (cursor.Next(part)) {
if (GetViewLODListManager()->Lookup(part->m_roiName.GetData()) == NULL && ViewLODList* lodList = GetViewLODListManager()->Lookup(part->m_roiName.GetData());
LoadWorldPart(*part, wdbFile) != SUCCESS) { if (lodList) {
lodList->Release();
}
if (lodList == NULL && LoadWorldPart(*part, wdbFile) != SUCCESS) {
return FAILURE; return FAILURE;
} }
} }

View File

@ -28,6 +28,7 @@ const char* g_clickedAtom = NULL;
MxBool g_unk0x100f67b8 = TRUE; MxBool g_unk0x100f67b8 = TRUE;
// FUNCTION: LEGO1 0x1005b790 // FUNCTION: LEGO1 0x1005b790
// STUB: BETA10 0x10088a8e
LegoInputManager::LegoInputManager() LegoInputManager::LegoInputManager()
{ {
m_keyboardNotifyList = NULL; m_keyboardNotifyList = NULL;
@ -55,11 +56,13 @@ LegoInputManager::~LegoInputManager()
} }
// FUNCTION: LEGO1 0x1005b960 // FUNCTION: LEGO1 0x1005b960
// STUB: BETA10 0x10088c9c
MxResult LegoInputManager::Create(HWND p_hwnd) MxResult LegoInputManager::Create(HWND p_hwnd)
{ {
MxResult result = SUCCESS; MxResult result = SUCCESS;
m_controlManager = new LegoControlManager; m_controlManager = new LegoControlManager;
assert(m_controlManager);
if (!m_keyboardNotifyList) { if (!m_keyboardNotifyList) {
m_keyboardNotifyList = new LegoNotifyList; m_keyboardNotifyList = new LegoNotifyList;
@ -612,6 +615,7 @@ MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touc
case e_arrowKeys: case e_arrowKeys:
switch (p_event->type) { switch (p_event->type) {
case SDL_EVENT_FINGER_UP: case SDL_EVENT_FINGER_UP:
case SDL_EVENT_FINGER_CANCELED:
m_touchFlags.erase(event.fingerID); m_touchFlags.erase(event.fingerID);
break; break;
case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_DOWN:
@ -647,6 +651,7 @@ MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touc
} }
break; break;
case SDL_EVENT_FINGER_UP: case SDL_EVENT_FINGER_UP:
case SDL_EVENT_FINGER_CANCELED:
if (event.fingerID == g_finger) { if (event.fingerID == g_finger) {
g_finger = 0; g_finger = 0;
m_touchVirtualThumb = {0, 0}; m_touchVirtualThumb = {0, 0};
@ -795,6 +800,7 @@ void LegoInputManager::UpdateLastInputMethod(SDL_Event* p_event)
case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_MOTION:
case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_DOWN:
case SDL_EVENT_FINGER_UP: case SDL_EVENT_FINGER_UP:
case SDL_EVENT_FINGER_CANCELED:
m_lastInputMethod = SDL_TouchID_v{p_event->tfinger.touchID}; m_lastInputMethod = SDL_TouchID_v{p_event->tfinger.touchID};
break; break;
} }

View File

@ -41,6 +41,7 @@ DECOMP_SIZE_ASSERT(LegoWorldList, 0x18)
DECOMP_SIZE_ASSERT(LegoWorldListCursor, 0x10) DECOMP_SIZE_ASSERT(LegoWorldListCursor, 0x10)
// GLOBAL: LEGO1 0x100f6718 // GLOBAL: LEGO1 0x100f6718
// GLOBAL: BETA10 0x101ee748
// STRING: LEGO1 0x100f6710 // STRING: LEGO1 0x100f6710
const char* g_current = "current"; const char* g_current = "current";
@ -51,12 +52,14 @@ LegoOmni::LegoOmni()
} }
// FUNCTION: LEGO1 0x10058b50 // FUNCTION: LEGO1 0x10058b50
// FUNCTION: BETA10 0x1008d128
LegoOmni::~LegoOmni() LegoOmni::~LegoOmni()
{ {
Destroy(); Destroy();
} }
// FUNCTION: LEGO1 0x10058bd0 // FUNCTION: LEGO1 0x10058bd0
// FUNCTION: BETA10 0x1008d1b4
void LegoOmni::Init() void LegoOmni::Init()
{ {
MxOmni::Init(); MxOmni::Init();
@ -74,12 +77,13 @@ void LegoOmni::Init()
m_animationManager = NULL; m_animationManager = NULL;
m_buildingManager = NULL; m_buildingManager = NULL;
m_bkgAudioManager = NULL; m_bkgAudioManager = NULL;
m_unk0x13c = TRUE; m_initialized = TRUE;
m_transitionManager = NULL; m_transitionManager = NULL;
m_version10 = FALSE; m_version10 = FALSE;
} }
// FUNCTION: LEGO1 0x10058c30 // FUNCTION: LEGO1 0x10058c30
// STUB: BETA10 0x1008d299
void LegoOmni::Destroy() void LegoOmni::Destroy()
{ {
AUTOLOCK(m_criticalSection); AUTOLOCK(m_criticalSection);
@ -122,6 +126,8 @@ void LegoOmni::Destroy()
m_textureContainer = NULL; m_textureContainer = NULL;
} }
LegoPartPresenter::Release();
if (m_viewLODListManager) { if (m_viewLODListManager) {
delete m_viewLODListManager; delete m_viewLODListManager;
m_viewLODListManager = NULL; m_viewLODListManager = NULL;
@ -155,13 +161,19 @@ void LegoOmni::Destroy()
MxOmni::Destroy(); MxOmni::Destroy();
} }
#ifdef BETA10
// FUNCTION: BETA10 0x100d4e5e
void EmptyFunction(int p_unknown)
{
}
#endif
// FUNCTION: LEGO1 0x10058e70 // FUNCTION: LEGO1 0x10058e70
// FUNCTION: BETA10 0x1008d6bf // FUNCTION: BETA10 0x1008d6bf
MxResult LegoOmni::Create(MxOmniCreateParam& p_param) MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
{ {
MxResult result = FAILURE; MxResult result = FAILURE;
AUTOLOCK(m_criticalSection); AUTOLOCK(m_criticalSection);
HWND hWnd = NULL;
p_param.CreateFlags().CreateObjectFactory(FALSE); p_param.CreateFlags().CreateObjectFactory(FALSE);
p_param.CreateFlags().CreateVideoManager(FALSE); p_param.CreateFlags().CreateVideoManager(FALSE);
@ -177,19 +189,19 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create MxOmni"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create MxOmni");
goto done; goto done;
} }
// LINE: BETA10 0x1008d7fa
if (!(m_objectFactory = new LegoObjectFactory())) { if (!(m_objectFactory = new LegoObjectFactory())) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoObjectFactory"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoObjectFactory");
goto done; goto done;
} }
// LINE: BETA10 0x1008d882
if (!(m_soundManager = new LegoSoundManager()) || m_soundManager->Create(10, 0) != SUCCESS) { if (!(m_soundManager = new LegoSoundManager()) || m_soundManager->Create(10, 0) != SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoSoundManager"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoSoundManager");
delete m_soundManager; delete m_soundManager;
m_soundManager = NULL; m_soundManager = NULL;
goto done; goto done;
} }
// LINE: BETA10 0x1008d990
if (!(m_videoManager = new LegoVideoManager()) || if (!(m_videoManager = new LegoVideoManager()) ||
m_videoManager->Create(p_param.GetVideoParam(), 100, 0) != SUCCESS) { m_videoManager->Create(p_param.GetVideoParam(), 100, 0) != SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoVideoManager"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoVideoManager");
@ -197,24 +209,51 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
m_videoManager = NULL; m_videoManager = NULL;
goto done; goto done;
} }
// LINE: BETA10 0x1008daa7
if (!(m_inputManager = new LegoInputManager()) || m_inputManager->Create(p_param.GetWindowHandle()) != SUCCESS) { if (!(m_inputManager = new LegoInputManager()) || m_inputManager->Create(p_param.GetWindowHandle()) != SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoInputManager"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoInputManager");
delete m_inputManager; delete m_inputManager;
m_inputManager = NULL; m_inputManager = NULL;
goto done; goto done;
} }
// LINE: BETA10 0x1008dbdb
m_viewLODListManager = new ViewLODListManager(); m_viewLODListManager = new ViewLODListManager();
// LINE: BETA10 0x1008dc32
m_textureContainer = new LegoTextureContainer(); m_textureContainer = new LegoTextureContainer();
#ifndef BETA10
m_textureContainer->SetOwnership(FALSE); m_textureContainer->SetOwnership(FALSE);
#else
// One more class is instantiated here in BETA10 that we don't find in LEGO1.
// Based on `LegoOmni::getTextureContainer()` we know that `LegoTextureContainer` is at LegoOmni's offset 0x230,
// so the first instantiation is `LegoTextureContainer` and the second one is the unknown one.
// We repeat the initialisation of LegoTextureContainer for the sake of a structural match,
// even though it is wrong semantically.
// LINE: BETA10 0x1008dc89
m_textureContainer = new LegoTextureContainer();
// Something else happens here starting at BETA10 0x1008dcdd that has not been decompiled.
// It involves external calls, bit manipulation, and two globals.
// Those appear to involve classes that are either not present in LEGO1 or we have the wrong names for them
// (like LegoMaterialCache).
#endif
// LINE: BETA10 0x1008dd17
LegoPathController::Init(); LegoPathController::Init();
m_characterManager = new LegoCharacterManager(); m_characterManager = new LegoCharacterManager();
m_plantManager = new LegoPlantManager(); m_plantManager = new LegoPlantManager();
// LINE: BETA10 0x1008ddca
m_animationManager = new LegoAnimationManager(); m_animationManager = new LegoAnimationManager();
m_buildingManager = new LegoBuildingManager(); m_buildingManager = new LegoBuildingManager();
// LINE: BETA10 0x1008de7b
m_gameState = new LegoGameState(); m_gameState = new LegoGameState();
// LINE: BETA10 0x1008ded5
m_worldList = new LegoWorldList(TRUE); m_worldList = new LegoWorldList(TRUE);
if (!m_viewLODListManager || !m_textureContainer || !m_worldList || !m_characterManager || !m_plantManager || if (!m_viewLODListManager || !m_textureContainer || !m_worldList || !m_characterManager || !m_plantManager ||
@ -228,33 +267,51 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
goto done; goto done;
} }
MxVariable* variable; MxVariable *visibilityVar, *cameraLocationVar, *cursorVar, *whoAmIVar, *debugVar;
// LINE: BETA10 0x1008dfbd
if (!(variable = new VisibilityVariable())) { visibilityVar = new VisibilityVariable();
if (!visibilityVar) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create VisibilityVariable"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create VisibilityVariable");
goto done; goto done;
} }
m_variableTable->SetVariable(variable); m_variableTable->SetVariable(visibilityVar);
if (!(variable = new CameraLocationVariable())) { // LINE: BETA10 0x1008e031
cameraLocationVar = new CameraLocationVariable();
if (!cameraLocationVar) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create CameraLocationVariable"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create CameraLocationVariable");
goto done; goto done;
} }
m_variableTable->SetVariable(variable); m_variableTable->SetVariable(cameraLocationVar);
if (!(variable = new CursorVariable())) { // LINE: BETA10 0x1008e0a5
cursorVar = new CursorVariable();
if (!cursorVar) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create CursorVariable"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create CursorVariable");
goto done; goto done;
} }
m_variableTable->SetVariable(variable); m_variableTable->SetVariable(cursorVar);
if (!(variable = new WhoAmIVariable())) { // LINE: BETA10 0x1008e119
whoAmIVar = new WhoAmIVariable();
if (!whoAmIVar) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create WhoAmIVariable"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create WhoAmIVariable");
goto done; goto done;
} }
m_variableTable->SetVariable(variable); m_variableTable->SetVariable(whoAmIVar);
#ifdef BETA10
debugVar = new DebugVariable();
if (!debugVar) {
goto done;
}
m_variableTable->SetVariable(debugVar);
#endif
// LINE: BETA10 0x1008e201
CreateScripts(); CreateScripts();
#ifndef BETA10
IslePathActor::RegisterSpawnLocations(); IslePathActor::RegisterSpawnLocations();
result = RegisterWorlds(); result = RegisterWorlds();
@ -262,30 +319,41 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create RegisterWorlds"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create RegisterWorlds");
goto done; goto done;
} }
#endif
if (!(m_bkgAudioManager = new MxBackgroundAudioManager())) { // LINE: BETA10 0x1008e206
m_bkgAudioManager = new MxBackgroundAudioManager();
if (!m_bkgAudioManager) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create MxBackgroundAudioManager"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create MxBackgroundAudioManager");
goto done; goto done;
} }
if (!(m_transitionManager = new MxTransitionManager())) { // LINE: BETA10 0x1008e27d
m_transitionManager = new MxTransitionManager();
if (m_transitionManager) {
if (m_transitionManager->GetDDrawSurfaceFromVideoManager() != SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxTransitionManager::GetDDrawSurfaceFromVideoManager failed");
goto done;
}
#ifdef BETA10
NotificationManager()->Register(this);
EmptyFunction(0);
#else
m_notificationManager->Register(this);
SetAppCursor(e_cursorBusy);
m_gameState->SetCurrentAct(LegoGameState::e_act1);
#endif
result = SUCCESS;
}
else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create MxTransitionManager"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create MxTransitionManager");
goto done;
} }
if (m_transitionManager->GetDDrawSurfaceFromVideoManager() != SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxTransitionManager::GetDDrawSurfaceFromVideoManager failed");
goto done;
}
m_notificationManager->Register(this);
SetAppCursor(e_cursorBusy);
m_gameState->SetCurrentAct(LegoGameState::e_act1);
result = SUCCESS;
done: done:
return result; return result;
// LINE: BETA10 0x1008e35d
} }
// FUNCTION: LEGO1 0x1005a5f0 // FUNCTION: LEGO1 0x1005a5f0
@ -400,6 +468,7 @@ LegoWorld* LegoOmni::FindWorld(const MxAtomId& p_atom, MxS32 p_entityid)
} }
// FUNCTION: LEGO1 0x1005b1d0 // FUNCTION: LEGO1 0x1005b1d0
// STUB: BETA10 0x1008e93e
void LegoOmni::DeleteObject(MxDSAction& p_dsAction) void LegoOmni::DeleteObject(MxDSAction& p_dsAction)
{ {
if (p_dsAction.GetAtomId().GetInternal() != NULL) { if (p_dsAction.GetAtomId().GetInternal() != NULL) {
@ -452,15 +521,16 @@ LegoROI* LegoOmni::FindROI(const char* p_name)
} }
// FUNCTION: LEGO1 0x1005b2f0 // FUNCTION: LEGO1 0x1005b2f0
// FUNCTION: BETA10 0x1008eb66
MxEntity* LegoOmni::AddToWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter) MxEntity* LegoOmni::AddToWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter)
{ {
LegoWorld* world = NULL; LegoWorld* world;
if (SDL_strcasecmp(p_id, g_current)) { if (SDL_strcasecmp(p_id, g_current)) {
world = FindWorld(MxAtomId(p_id, e_lowerCase2), p_entityId); world = FindWorld(MxAtomId(p_id, e_lowerCase2), p_entityId);
} }
else { else {
world = this->m_currentWorld; world = GetCurrentWorld();
} }
if (world != NULL) { if (world != NULL) {
@ -471,14 +541,17 @@ MxEntity* LegoOmni::AddToWorld(const char* p_id, MxS32 p_entityId, MxPresenter*
} }
// FUNCTION: LEGO1 0x1005b3a0 // FUNCTION: LEGO1 0x1005b3a0
// FUNCTION: BETA10 0x1008ec27
void LegoOmni::NotifyCurrentEntity(const MxNotificationParam& p_param) void LegoOmni::NotifyCurrentEntity(const MxNotificationParam& p_param)
{ {
if (m_currentWorld) { LegoWorld* currentWorld = GetCurrentWorld();
NotificationManager()->Send(m_currentWorld, p_param); if (currentWorld) {
NotificationManager()->Send(currentWorld, p_param);
} }
} }
// FUNCTION: LEGO1 0x1005b3c0 // FUNCTION: LEGO1 0x1005b3c0
// FUNCTION: BETA10 0x1008ec72
MxBool LegoOmni::DoesEntityExist(MxDSAction& p_dsAction) MxBool LegoOmni::DoesEntityExist(MxDSAction& p_dsAction)
{ {
if (MxOmni::DoesEntityExist(p_dsAction)) { if (MxOmni::DoesEntityExist(p_dsAction)) {
@ -584,12 +657,19 @@ void LegoOmni::CreateBackgroundAudio()
} }
// FUNCTION: LEGO1 0x1005b580 // FUNCTION: LEGO1 0x1005b580
// FUNCTION: BETA10 0x1008f7e0
MxResult LegoOmni::Start(MxDSAction* p_dsAction) MxResult LegoOmni::Start(MxDSAction* p_dsAction)
{ {
MxResult result = MxOmni::Start(p_dsAction); MxResult result = MxOmni::Start(p_dsAction);
#ifdef BETA10
this->m_action = *p_dsAction;
#else
// TODO: This is likely an inlined `MxDsAction::operator=`, see the BETA10 code.
// As of this commit, the operator is not inlined automatically.
this->m_action.SetAtomId(p_dsAction->GetAtomId()); this->m_action.SetAtomId(p_dsAction->GetAtomId());
this->m_action.SetObjectId(p_dsAction->GetObjectId()); this->m_action.SetObjectId(p_dsAction->GetObjectId());
this->m_action.SetUnknown24(p_dsAction->GetUnknown24()); this->m_action.SetUnknown24(p_dsAction->GetUnknown24());
#endif
return result; return result;
} }

View File

@ -91,6 +91,7 @@ MxAtomId* g_creditsScript = NULL;
MxAtomId* g_nocdSourceName = NULL; MxAtomId* g_nocdSourceName = NULL;
// FUNCTION: LEGO1 0x100528e0 // FUNCTION: LEGO1 0x100528e0
// STUB: BETA10 0x100f6133
void CreateScripts() void CreateScripts()
{ {
g_copterScript = new MxAtomId("\\lego\\scripts\\build\\copter", e_lowerCase2); g_copterScript = new MxAtomId("\\lego\\scripts\\build\\copter", e_lowerCase2);

View File

@ -2,7 +2,7 @@
#include "anim/legoanim.h" #include "anim/legoanim.h"
#include "define.h" #include "define.h"
#include "legolocomotionanimpresenter.h" #include "legoanimpresenter.h"
#include "legopathboundary.h" #include "legopathboundary.h"
#include "legoworld.h" #include "legoworld.h"
#include "misc.h" #include "misc.h"
@ -133,7 +133,7 @@ MxResult LegoAnimActor::FUN_1001c360(float p_und, Matrix4& p_transform)
} }
for (MxS32 j = 0; j < n->GetNumChildren(); j++) { for (MxS32 j = 0; j < n->GetNumChildren(); j++) {
LegoROI::FUN_100a8e80(n->GetChild(j), p_transform, p_und, roiMap); LegoROI::ApplyAnimationTransformation(n->GetChild(j), p_transform, p_und, roiMap);
} }
if (m_cameraFlag) { if (m_cameraFlag) {

View File

@ -1,8 +1,8 @@
#include "legoextraactor.h" #include "legoextraactor.h"
#include "anim/legoanim.h" #include "anim/legoanim.h"
#include "legoanimpresenter.h"
#include "legocachesoundmanager.h" #include "legocachesoundmanager.h"
#include "legolocomotionanimpresenter.h"
#include "legosoundmanager.h" #include "legosoundmanager.h"
#include "legoworld.h" #include "legoworld.h"
#include "misc.h" #include "misc.h"
@ -235,7 +235,9 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool)
assert(m_roi); assert(m_roi);
assert(SoundManager()->GetCacheSoundManager()); assert(SoundManager()->GetCacheSoundManager());
SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE); SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE);
HitActorEvent(); if (p_actor->GetUserNavFlag()) {
EmitGameEvent(e_hitActor);
}
m_scheduledTime = Timer()->GetTime() + m_disAnim->GetDuration(); m_scheduledTime = Timer()->GetTime() + m_disAnim->GetDuration();
m_prevWorldSpeed = GetWorldSpeed(); m_prevWorldSpeed = GetWorldSpeed();
VTable0xc4(); VTable0xc4();
@ -249,7 +251,9 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool)
LegoROI* roi = GetROI(); LegoROI* roi = GetROI();
assert(roi); assert(roi);
SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE); SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE);
HitActorEvent(); if (p_actor->GetUserNavFlag()) {
EmitGameEvent(e_hitActor);
}
VTable0xc4(); VTable0xc4();
SetActorState(c_two | c_noCollide); SetActorState(c_two | c_noCollide);
Mx3DPointFloat dir = p_actor->GetWorldDirection(); Mx3DPointFloat dir = p_actor->GetWorldDirection();
@ -375,7 +379,7 @@ void LegoExtraActor::Animate(float p_time)
MxS32 count = root->GetNumChildren(); MxS32 count = root->GetNumChildren();
for (MxS32 i = 0; i < count; i++) { for (MxS32 i = 0; i < count; i++) {
LegoROI::FUN_100a8e80(root->GetChild(i), matrix, duration2, laas->m_roiMap); LegoROI::ApplyAnimationTransformation(root->GetChild(i), matrix, duration2, laas->m_roiMap);
} }
} }
} }

View File

@ -440,7 +440,7 @@ void LegoPathActor::Animate(float p_time)
LegoWorld* world = CurrentWorld(); LegoWorld* world = CurrentWorld();
if (world) { if (world) {
world->GetCameraController()->FUN_10012290(DTOR(m_unk0x14c)); world->GetCameraController()->RotateZ(DTOR(m_unk0x14c));
} }
} }
} }

View File

@ -2,7 +2,7 @@
#include "decomp.h" #include "decomp.h"
#include "geom/legoorientededge.h" #include "geom/legoorientededge.h"
#include "legolocomotionanimpresenter.h" #include "legoanimpresenter.h"
#include "legopathactor.h" #include "legopathactor.h"
#include "legopathstruct.h" #include "legopathstruct.h"

View File

@ -3,7 +3,7 @@
#include "isle.h" #include "isle.h"
#include "jukebox.h" #include "jukebox.h"
#include "jukebox_actions.h" #include "jukebox_actions.h"
#include "legohideanimpresenter.h" #include "legoanimpresenter.h"
#include "legopathactor.h" #include "legopathactor.h"
#include "legoutils.h" #include "legoutils.h"
#include "misc.h" #include "misc.h"

View File

@ -5,8 +5,8 @@
#include "isle.h" #include "isle.h"
#include "jukebox_actions.h" #include "jukebox_actions.h"
#include "legoanimationmanager.h" #include "legoanimationmanager.h"
#include "legoanimpresenter.h"
#include "legocontrolmanager.h" #include "legocontrolmanager.h"
#include "legohideanimpresenter.h"
#include "legomain.h" #include "legomain.h"
#include "legonavcontroller.h" #include "legonavcontroller.h"
#include "legopathstruct.h" #include "legopathstruct.h"
@ -267,6 +267,8 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
FALSE, FALSE,
TRUE TRUE
); );
EmitGameEvent(e_raceFinished);
} }
result = 1; result = 1;
@ -337,7 +339,7 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
// FUNCTION: LEGO1 0x10017650 // FUNCTION: LEGO1 0x10017650
MxLong CarRace::HandleControl(LegoControlManagerNotificationParam& p_param) MxLong CarRace::HandleControl(LegoControlManagerNotificationParam& p_param)
{ {
if (p_param.m_unk0x28 == 1) { if (p_param.m_enabledChild == 1) {
switch (p_param.m_clickedObjectId) { switch (p_param.m_clickedObjectId) {
case 3: case 3:
InvokeAction(Extra::e_stop, *g_carraceScript, CarraceScript::c_irtx08ra_PlayWav, NULL); InvokeAction(Extra::e_stop, *g_carraceScript, CarraceScript::c_irtx08ra_PlayWav, NULL);

View File

@ -6,8 +6,8 @@
#include "jetski_actions.h" #include "jetski_actions.h"
#include "jukebox_actions.h" #include "jukebox_actions.h"
#include "legoanimationmanager.h" #include "legoanimationmanager.h"
#include "legoanimpresenter.h"
#include "legocontrolmanager.h" #include "legocontrolmanager.h"
#include "legohideanimpresenter.h"
#include "legomain.h" #include "legomain.h"
#include "legopathstruct.h" #include "legopathstruct.h"
#include "legoracers.h" #include "legoracers.h"
@ -126,7 +126,7 @@ MxLong JetskiRace::HandleControl(LegoControlManagerNotificationParam& p_param)
{ {
MxLong result = 0; MxLong result = 0;
if (p_param.m_unk0x28 == 1) { if (p_param.m_enabledChild == 1) {
switch (p_param.m_clickedObjectId) { switch (p_param.m_clickedObjectId) {
case JetraceScript::c_JetskiArms_Ctl: case JetraceScript::c_JetskiArms_Ctl:
m_act1State->m_state = Act1State::e_none; m_act1State->m_state = Act1State::e_none;
@ -206,6 +206,7 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
m_destLocation = LegoGameState::e_jetrace2; m_destLocation = LegoGameState::e_jetrace2;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
EmitGameEvent(e_raceFinished);
} }
result = 1; result = 1;

View File

@ -129,7 +129,7 @@ MxLong LegoRaceMap::Notify(MxParam& p_param)
if (param.GetNotification() == c_notificationControl && if (param.GetNotification() == c_notificationControl &&
m_Map_Ctl->GetAction()->GetObjectId() == ((LegoControlManagerNotificationParam&) p_param).m_clickedObjectId) { m_Map_Ctl->GetAction()->GetObjectId() == ((LegoControlManagerNotificationParam&) p_param).m_clickedObjectId) {
if (((LegoControlManagerNotificationParam&) p_param).m_unk0x28 == 1) { if (((LegoControlManagerNotificationParam&) p_param).m_enabledChild == 1) {
m_unk0x08 = TRUE; m_unk0x08 = TRUE;
FUN_1005d4b0(); FUN_1005d4b0();
m_stillPresenter->Enable(TRUE); m_stillPresenter->Enable(TRUE);

View File

@ -340,10 +340,10 @@ void LegoRaceCar::KickCamera(float p_param)
transformationMatrix.SetIdentity(); transformationMatrix.SetIdentity();
// Possible bug in the original code: The first argument is not initialized // Possible bug in the original code: The first argument is not initialized
a->GetAnimTreePtr()->GetCamAnim()->FUN_1009f490(deltaTime, transformationMatrix); a->GetAnimTreePtr()->GetCamAnim()->CalculateCameraTransform(deltaTime, transformationMatrix);
if (r->GetCameraController()) { if (r->GetCameraController()) {
r->GetCameraController()->FUN_100123e0(transformationMatrix, 0); r->GetCameraController()->TransformPointOfView(transformationMatrix, 0);
} }
m_roi->SetLocal2World(transformationMatrix); m_roi->SetLocal2World(transformationMatrix);
@ -392,6 +392,7 @@ MxU32 LegoRaceCar::HandleSkeletonKicks(float p_param1)
m_kickStart = p_param1; m_kickStart = p_param1;
SoundManager()->GetCacheSoundManager()->Play(g_soundSkel3, NULL, FALSE); SoundManager()->GetCacheSoundManager()->Play(g_soundSkel3, NULL, FALSE);
EmitGameEvent(e_skeletonKick);
return TRUE; return TRUE;
} }
@ -528,6 +529,9 @@ MxResult LegoRaceCar::HitActor(LegoPathActor* p_actor, MxBool p_bool)
} }
} }
} }
else {
EmitGameEvent(e_hitActor);
}
return SUCCESS; return SUCCESS;
} }
@ -726,6 +730,9 @@ MxResult LegoJetski::HitActor(LegoPathActor* p_actor, MxBool p_bool)
} }
} }
} }
else {
EmitGameEvent(e_hitActor);
}
return SUCCESS; return SUCCESS;
} }

View File

@ -3,6 +3,7 @@
#include "3dmanager/lego3dmanager.h" #include "3dmanager/lego3dmanager.h"
#include "anim/legoanim.h" #include "anim/legoanim.h"
#include "define.h" #include "define.h"
#include "legoanimactor.h"
#include "legoanimationmanager.h" #include "legoanimationmanager.h"
#include "legoanimmmpresenter.h" #include "legoanimmmpresenter.h"
#include "legocameracontroller.h" #include "legocameracontroller.h"
@ -30,6 +31,10 @@
#include <stdio.h> #include <stdio.h>
DECOMP_SIZE_ASSERT(LegoAnimPresenter, 0xbc) DECOMP_SIZE_ASSERT(LegoAnimPresenter, 0xbc)
DECOMP_SIZE_ASSERT(LegoLoopingAnimPresenter, 0xc0)
DECOMP_SIZE_ASSERT(LegoLocomotionAnimPresenter, 0xd8)
DECOMP_SIZE_ASSERT(LegoHideAnimPresenter, 0xc4)
DECOMP_SIZE_ASSERT(LegoHideAnimStruct, 0x08)
// FUNCTION: LEGO1 0x10068420 // FUNCTION: LEGO1 0x10068420
// FUNCTION: BETA10 0x1004e5f0 // FUNCTION: BETA10 0x1004e5f0
@ -909,7 +914,7 @@ void LegoAnimPresenter::FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p
} }
} }
LegoROI::FUN_100a8fd0(root, mat, p_time, m_roiMap); LegoROI::ApplyTransform(root, mat, p_time, m_roiMap);
} }
// FUNCTION: LEGO1 0x1006b9a0 // FUNCTION: LEGO1 0x1006b9a0
@ -936,14 +941,14 @@ void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p
if (p_anim->GetCamAnim() != NULL) { if (p_anim->GetCamAnim() != NULL) {
MxMatrix transform(mat); MxMatrix transform(mat);
p_anim->GetCamAnim()->FUN_1009f490(p_time, transform); p_anim->GetCamAnim()->CalculateCameraTransform(p_time, transform);
if (m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { if (m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) {
m_currentWorld->GetCameraController()->FUN_100123e0(transform, 0); m_currentWorld->GetCameraController()->TransformPointOfView(transform, FALSE);
} }
} }
LegoROI::FUN_100a8e80(root, mat, p_time, m_roiMap); LegoROI::ApplyAnimationTransformation(root, mat, p_time, m_roiMap);
} }
// FUNCTION: LEGO1 0x1006bac0 // FUNCTION: LEGO1 0x1006bac0
@ -1219,3 +1224,439 @@ MxResult LegoAnimPresenter::VTable0x98(LegoPathBoundary* p_boundary)
return SUCCESS; return SUCCESS;
} }
// FUNCTION: LEGO1 0x1006caa0
// FUNCTION: BETA10 0x1005223d
void LegoLoopingAnimPresenter::StreamingTickle()
{
if (m_subscriber->PeekData()) {
MxStreamChunk* chunk = m_subscriber->PopData();
m_subscriber->FreeDataChunk(chunk);
}
if (m_unk0x95) {
ProgressTickleState(e_done);
if (m_compositePresenter) {
if (m_compositePresenter->IsA("LegoAnimMMPresenter")) {
m_compositePresenter->VTable0x60(this);
}
}
}
else {
if (m_action->GetDuration() != -1) {
if (m_action->GetElapsedTime() > m_action->GetDuration() + m_action->GetStartTime()) {
m_unk0x95 = TRUE;
}
}
}
}
// FUNCTION: LEGO1 0x1006cb40
// FUNCTION: BETA10 0x1005239a
void LegoLoopingAnimPresenter::PutFrame()
{
MxLong time;
if (m_action->GetStartTime() <= m_action->GetElapsedTime()) {
time = (m_action->GetElapsedTime() - m_action->GetStartTime()) % m_anim->GetDuration();
}
else {
time = 0;
}
FUN_1006b9a0(m_anim, time, m_unk0x78);
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());
Vector3 pos(mat[0]);
Vector3 dir(mat[1]);
Vector3 up(mat[2]);
Vector3 und(mat[3]);
float possqr = sqrt(pos.LenSquared());
float dirsqr = sqrt(dir.LenSquared());
float upsqr = sqrt(up.LenSquared());
up = und;
up -= m_currentWorld->GetCameraController()->GetWorldLocation();
dir /= dirsqr;
pos.EqualsCross(dir, up);
pos.Unitize();
up.EqualsCross(pos, dir);
pos *= possqr;
dir *= dirsqr;
up *= upsqr;
m_unk0x8c[i]->SetLocal2World(mat);
m_unk0x8c[i]->WrappedUpdateWorldData();
}
}
}
}
// FUNCTION: LEGO1 0x1006cdd0
LegoLocomotionAnimPresenter::LegoLocomotionAnimPresenter()
{
Init();
}
// FUNCTION: LEGO1 0x1006d050
LegoLocomotionAnimPresenter::~LegoLocomotionAnimPresenter()
{
Destroy(TRUE);
}
// FUNCTION: LEGO1 0x1006d0b0
void LegoLocomotionAnimPresenter::Init()
{
m_unk0xc0 = 0;
m_unk0xc4 = NULL;
m_unk0xcc = -1;
m_unk0xd0 = -1;
m_roiMapList = NULL;
m_unk0xd4 = 0;
}
// FUNCTION: LEGO1 0x1006d0e0
void LegoLocomotionAnimPresenter::Destroy(MxBool p_fromDestructor)
{
ENTER(m_criticalSection);
if (m_unk0xc4) {
delete[] m_unk0xc4;
}
if (m_roiMapList) {
delete m_roiMapList;
}
m_roiMap = NULL;
Init();
m_criticalSection.Leave();
if (!p_fromDestructor) {
LegoLoopingAnimPresenter::Destroy();
}
}
// FUNCTION: LEGO1 0x1006d140
MxResult LegoLocomotionAnimPresenter::CreateAnim(MxStreamChunk* p_chunk)
{
MxResult result = LegoAnimPresenter::CreateAnim(p_chunk);
return result == SUCCESS ? SUCCESS : result;
}
// FUNCTION: LEGO1 0x1006d160
// FUNCTION: BETA10 0x100528c7
MxResult LegoLocomotionAnimPresenter::AddToManager()
{
m_roiMapList = new LegoROIMapList();
if (m_roiMapList == NULL) {
return FAILURE;
}
return LegoAnimPresenter::AddToManager();
}
// FUNCTION: LEGO1 0x1006d5b0
void LegoLocomotionAnimPresenter::Destroy()
{
Destroy(FALSE);
}
// FUNCTION: LEGO1 0x1006d5c0
void LegoLocomotionAnimPresenter::PutFrame()
{
// Empty
}
// FUNCTION: LEGO1 0x1006d5d0
void LegoLocomotionAnimPresenter::ReadyTickle()
{
LegoLoopingAnimPresenter::ReadyTickle();
if (m_currentWorld != NULL && m_currentTickleState == e_starting) {
m_currentWorld->Add(this);
if (m_compositePresenter != NULL) {
SendToCompositePresenter(Lego());
}
m_unk0xd4++;
}
}
// FUNCTION: LEGO1 0x1006d610
// FUNCTION: BETA10 0x10052a34
void LegoLocomotionAnimPresenter::StartingTickle()
{
if (m_subscriber->PeekData()) {
MxStreamChunk* chunk = m_subscriber->PopData();
m_subscriber->FreeDataChunk(chunk);
}
if (m_roiMapList->GetNumElements() != 0) {
ProgressTickleState(e_streaming);
}
}
// FUNCTION: LEGO1 0x1006d660
void LegoLocomotionAnimPresenter::StreamingTickle()
{
if (m_unk0xd4 == 0) {
EndAction();
}
}
// FUNCTION: LEGO1 0x1006d670
void LegoLocomotionAnimPresenter::EndAction()
{
if (m_action) {
MxVideoPresenter::EndAction();
}
}
// FUNCTION: LEGO1 0x1006d680
// FUNCTION: BETA10 0x10052b3d
void LegoLocomotionAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value)
{
// This asserts that LegoLocomotionAnimPresenter is contained in legoanimpresenter.cpp
AUTOLOCK(m_criticalSection);
MxVariableTable* variableTable = VariableTable();
const char* key = ((LegoAnimNodeData*) m_anim->GetRoot()->GetData())->GetName();
variableTable->SetVariable(key, p_actor->GetROI()->GetName());
FUN_100695c0();
FUN_10069b10();
if (m_roiMap != NULL) {
m_roiMapList->Append(m_roiMap);
p_actor->FUN_1001c450(m_anim, p_value, m_roiMap, m_roiMapSize);
m_roiMap = NULL;
}
variableTable->SetVariable(key, "");
if (m_sceneROIs != NULL) {
delete m_sceneROIs;
m_sceneROIs = NULL;
}
}
// We do not have any hard evidence that `LegoHideAnimPresenter` is part of this file as well.
// However, since all of the other AnimPresenters are in the same file, it is reasonable to assume
// that the same holds here.
// FUNCTION: LEGO1 0x1006d7e0
LegoHideAnimPresenter::LegoHideAnimPresenter()
{
Init();
}
// FUNCTION: LEGO1 0x1006d9f0
LegoHideAnimPresenter::~LegoHideAnimPresenter()
{
Destroy(TRUE);
}
// FUNCTION: LEGO1 0x1006da50
void LegoHideAnimPresenter::Init()
{
m_boundaryMap = NULL;
}
// FUNCTION: LEGO1 0x1006da60
void LegoHideAnimPresenter::Destroy(MxBool p_fromDestructor)
{
ENTER(m_criticalSection);
if (m_boundaryMap) {
delete[] m_boundaryMap;
}
Init();
m_criticalSection.Leave();
// This appears to be a bug, since it results in an endless loop
if (!p_fromDestructor) {
LegoHideAnimPresenter::Destroy();
}
}
// FUNCTION: LEGO1 0x1006dab0
MxResult LegoHideAnimPresenter::AddToManager()
{
return LegoAnimPresenter::AddToManager();
}
// FUNCTION: LEGO1 0x1006dac0
void LegoHideAnimPresenter::Destroy()
{
Destroy(FALSE);
}
// FUNCTION: LEGO1 0x1006dad0
void LegoHideAnimPresenter::PutFrame()
{
}
// FUNCTION: LEGO1 0x1006dae0
// FUNCTION: BETA10 0x100530f4
void LegoHideAnimPresenter::ReadyTickle()
{
LegoLoopingAnimPresenter::ReadyTickle();
if (m_currentWorld) {
if (m_currentTickleState == e_starting && m_compositePresenter != NULL) {
SendToCompositePresenter(Lego());
}
m_currentWorld->Add(this);
}
}
// FUNCTION: LEGO1 0x1006db20
// FUNCTION: BETA10 0x1005316b
void LegoHideAnimPresenter::StartingTickle()
{
LegoLoopingAnimPresenter::StartingTickle();
if (m_currentTickleState == e_streaming) {
FUN_1006dc10();
FUN_1006db40(0);
}
}
// FUNCTION: LEGO1 0x1006db40
// FUNCTION: BETA10 0x100531ab
void LegoHideAnimPresenter::FUN_1006db40(LegoTime p_time)
{
FUN_1006db60(m_anim->GetRoot(), p_time);
}
// FUNCTION: LEGO1 0x1006db60
// FUNCTION: BETA10 0x100531de
void LegoHideAnimPresenter::FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time)
{
LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData();
MxBool newB = FALSE;
MxBool previousB = FALSE;
if (m_roiMap != NULL) {
LegoROI* roi = m_roiMap[data->GetROIIndex()];
if (roi != NULL) {
newB = data->GetVisibility(p_time);
previousB = roi->GetVisibility();
roi->SetVisibility(newB);
}
}
if (m_boundaryMap != NULL) {
LegoPathBoundary* boundary = m_boundaryMap[data->GetBoundaryIndex()];
if (boundary != NULL) {
newB = data->GetVisibility(p_time);
previousB = boundary->GetFlag0x10();
boundary->SetFlag0x10(newB);
}
}
for (MxS32 i = 0; i < p_node->GetNumChildren(); i++) {
FUN_1006db60(p_node->GetChild(i), p_time);
}
}
// FUNCTION: LEGO1 0x1006dc10
// FUNCTION: BETA10 0x100532fd
void LegoHideAnimPresenter::FUN_1006dc10()
{
LegoHideAnimStructMap anims;
FUN_1006e3f0(anims, m_anim->GetRoot());
if (m_boundaryMap != NULL) {
delete[] m_boundaryMap;
}
m_boundaryMap = new LegoPathBoundary*[anims.size() + 1];
m_boundaryMap[0] = NULL;
for (LegoHideAnimStructMap::iterator it = anims.begin(); !(it == anims.end()); it++) {
m_boundaryMap[(*it).second.m_index] = (*it).second.m_boundary;
delete[] const_cast<char*>((*it).first);
}
}
// FUNCTION: LEGO1 0x1006e3f0
// FUNCTION: BETA10 0x1005345e
void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node)
{
LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData();
const char* name = data->GetName();
if (name != NULL) {
LegoPathBoundary* boundary = m_currentWorld->FindPathBoundary(name);
if (boundary != NULL) {
FUN_1006e470(p_map, data, name, boundary);
}
else {
data->SetBoundaryIndex(0);
}
}
MxS32 count = p_node->GetNumChildren();
for (MxS32 i = 0; i < count; i++) {
FUN_1006e3f0(p_map, p_node->GetChild(i));
}
}
// FUNCTION: LEGO1 0x1006e470
// FUNCTION: BETA10 0x10053520
void LegoHideAnimPresenter::FUN_1006e470(
LegoHideAnimStructMap& p_map,
LegoAnimNodeData* p_data,
const char* p_name,
LegoPathBoundary* p_boundary
)
{
LegoHideAnimStructMap::iterator it;
it = p_map.find(p_name);
if (it == p_map.end()) {
LegoHideAnimStruct animStruct;
animStruct.m_index = p_map.size() + 1;
animStruct.m_boundary = p_boundary;
p_data->SetBoundaryIndex(animStruct.m_index);
char* name = new char[strlen(p_name) + 1];
strcpy(name, p_name);
p_map[name] = animStruct;
}
else {
p_data->SetBoundaryIndex((*it).second.m_index);
}
}
// FUNCTION: LEGO1 0x1006e9e0
// FUNCTION: BETA10 0x100535ef
void LegoHideAnimPresenter::EndAction()
{
if (m_action) {
MxVideoPresenter::EndAction();
if (m_currentWorld) {
m_currentWorld->Remove(this);
}
}
}

View File

@ -4,6 +4,8 @@
#include "misc/legocontainer.h" #include "misc/legocontainer.h"
#include "mxdsaction.h" #include "mxdsaction.h"
#include <assert.h>
DECOMP_SIZE_ASSERT(LegoFlcTexturePresenter, 0x70) DECOMP_SIZE_ASSERT(LegoFlcTexturePresenter, 0x70)
// FUNCTION: LEGO1 0x1005de80 // FUNCTION: LEGO1 0x1005de80
@ -27,11 +29,14 @@ void LegoFlcTexturePresenter::StartingTickle()
char* pp; char* pp;
char extraCopy[128]; char extraCopy[128];
m_action->GetExtra(extraLength, pp); m_action->GetExtra(extraLength, pp);
assert(pp);
if (pp != NULL) { if (pp != NULL) {
strcpy(extraCopy, pp); strcpy(extraCopy, pp);
strcat(extraCopy, ".gif"); strcat(extraCopy, ".gif");
m_texture = TextureContainer()->Get(extraCopy); LegoTextureContainer* textureContainer = TextureContainer();
assert(textureContainer);
m_texture = textureContainer->Get(extraCopy);
} }
MxFlcPresenter::StartingTickle(); MxFlcPresenter::StartingTickle();

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