diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70827bfb..6032d85f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,8 +35,10 @@ jobs: matrix: include: - { 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 (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: '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}' } @@ -126,7 +128,7 @@ jobs: -DISLE_BUILD_CONFIG=${{ !!matrix.config }} \ -DENABLE_CLANG_TIDY=${{ !!matrix.clang-tidy }} \ -DISLE_WERROR=${{ !!matrix.werror }} \ - -DISLE_DEBUG=OFF \ + -DISLE_DEBUG=${{ matrix.debug || 'OFF' }} \ -Werror=dev - name: Build (CMake) diff --git a/.pylintrc b/.pylintrc index ab83fceb..68704fad 100644 --- a/.pylintrc +++ b/.pylintrc @@ -88,7 +88,7 @@ persistent=yes # Minimum Python version to use for version dependent checks. Will default to # the version used to run pylint. -py-version=3.11 +py-version=3.12 # Discover python modules and packages in the file system subtree. recursive=no diff --git a/CMakeLists.txt b/CMakeLists.txt index ed8ad61a..b9c666fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ endif() if (EMSCRIPTEN) 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) endif() @@ -39,7 +39,7 @@ else() endif() 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_ASAN "Enable Address Sanitizer" OFF) @@ -184,6 +184,8 @@ target_include_directories(lego1 PUBLIC "$:DirectX5::DirectX5>) +# Allow unconditional include of miniwin/miniwind3d.h +target_link_libraries(lego1 PRIVATE miniwin-headers) if(WIN32) set_property(TARGET lego1 PROPERTY PREFIX "") endif() @@ -314,10 +316,10 @@ target_sources(lego1 PRIVATE LEGO1/omni/src/common/mxcompositepresenter.cpp LEGO1/omni/src/common/mxcore.cpp LEGO1/omni/src/common/mxdebug.cpp - LEGO1/omni/src/common/mxmediamanager.cpp LEGO1/omni/src/common/mxmediapresenter.cpp LEGO1/omni/src/common/mxmisc.cpp LEGO1/omni/src/common/mxobjectfactory.cpp + LEGO1/omni/src/common/mxpresentationmanager.cpp LEGO1/omni/src/common/mxpresenter.cpp LEGO1/omni/src/common/mxstring.cpp LEGO1/omni/src/common/mxticklemanager.cpp @@ -328,7 +330,7 @@ target_sources(lego1 PRIVATE LEGO1/omni/src/entity/mxentity.cpp LEGO1/omni/src/event/mxeventmanager.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/mxomnicreateparam.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/video/legoanimpresenter.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/legopalettepresenter.cpp LEGO1/lego/legoomni/src/video/legopartpresenter.cpp diff --git a/CONFIG/qt/MainDlg.cpp b/CONFIG/qt/MainDlg.cpp index 3f69d096..5ae140c3 100644 --- a/CONFIG/qt/MainDlg.cpp +++ b/CONFIG/qt/MainDlg.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -54,15 +56,18 @@ CMainDialog::CMainDialog(QWidget* pParent) : QDialog(pParent) this, &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->musicCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxMusic); 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->textureCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxTexture); connect(m_ui->touchComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::TouchControlsChanged); 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->cancelButton, &QPushButton::clicked, this, &CMainDialog::reject); 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::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->xResSpinBox, &QSpinBox::valueChanged, this, &CMainDialog::XResChanged); 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->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(); return true; } @@ -258,18 +285,30 @@ void CMainDialog::UpdateInterface() else { 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->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->touchComboBox->setCurrentIndex(currentConfigApp->m_touch_scheme); m_ui->transitionTypeComboBox->setCurrentIndex(currentConfigApp->m_transition_type); m_ui->dataPath->setText(QString::fromStdString(currentConfigApp->m_cd_path)); m_ui->savePath->setText(QString::fromStdString(currentConfigApp->m_save_path)); + m_ui->textureCheckBox->setChecked(currentConfigApp->m_texture_load); m_ui->texturePath->setText(QString::fromStdString(currentConfigApp->m_texture_path)); - m_ui->texturePath->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->yResSpinBox->setValue(currentConfigApp->m_y_res); m_ui->framerateSpinBox->setValue(static_cast(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 @@ -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 void CMainDialog::OnCheckboxMusic(bool checked) { @@ -344,21 +428,6 @@ void CMainDialog::OnCheckboxMusic(bool checked) 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) { currentConfigApp->m_haptic = checked; @@ -387,6 +456,15 @@ void CMainDialog::TransitionTypeChanged(int index) 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() { QString data_path = QString::fromStdString(currentConfigApp->m_cd_path); @@ -458,15 +536,29 @@ void CMainDialog::SavePathEdited() void CMainDialog::MaxLoDChanged(int value) { currentConfigApp->m_max_lod = static_cast(value) / 10.0f; - m_ui->LoDNum->setNum(value); m_modified = true; + UpdateInterface(); } void CMainDialog::MaxActorsChanged(int value) { currentConfigApp->m_max_actors = value; - m_ui->maxActorsNum->setNum(value); 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() diff --git a/CONFIG/qt/MainDlg.h b/CONFIG/qt/MainDlg.h index ece4dbfd..0aaeeb12 100644 --- a/CONFIG/qt/MainDlg.h +++ b/CONFIG/qt/MainDlg.h @@ -7,6 +7,7 @@ #include #include +#include namespace Ui { @@ -29,6 +30,7 @@ class CMainDialog : public QDialog { bool m_modified = false; bool m_advanced = false; Ui::MainDialog* m_ui = nullptr; + SDL_DisplayMode** displayModes; void keyReleaseEvent(QKeyEvent* event) override; bool OnInitDialog(); @@ -40,13 +42,15 @@ private slots: void OnRadiobuttonModelHighQuality(bool checked); void OnRadiobuttonTextureLowQuality(bool checked); void OnRadiobuttonTextureHighQuality(bool checked); + void OnRadioWindowed(bool checked); + void OnRadioFullscreen(bool checked); + void OnRadioExclusiveFullscreen(bool checked); void OnCheckboxMusic(bool checked); - void OnCheckboxFullscreen(bool checked); - void OnCheckboxExclusiveFullscreen(bool checked); void OnCheckboxRumble(bool checked); void OnCheckboxTexture(bool checked); void TouchControlsChanged(int index); void TransitionTypeChanged(int index); + void ExclusiveResolutionChanged(int index); void accept() override; void reject() override; void launch(); @@ -56,6 +60,8 @@ private slots: void SavePathEdited(); void MaxLoDChanged(int value); void MaxActorsChanged(int value); + void MSAAChanged(int value); + void AFChanged(int value); void SelectTexturePathDialog(); void TexturePathEdited(); void XResChanged(int i); diff --git a/CONFIG/qt/config.cpp b/CONFIG/qt/config.cpp index d0f1dda6..766cecd4 100644 --- a/CONFIG/qt/config.cpp +++ b/CONFIG/qt/config.cpp @@ -68,8 +68,9 @@ bool CConfigApp::InitInstance() } SDL_DestroyWindow(window); m_aspect_ratio = 0; - m_x_res = 640; - m_y_res = 480; + m_exf_x_res = m_x_res = 640; + m_exf_y_res = m_y_res = 480; + m_exf_fps = 60.00f; m_frame_delta = 10.0f; m_driver = NULL; m_device = NULL; @@ -83,6 +84,8 @@ bool CConfigApp::InitInstance() m_3d_video_ram = FALSE; m_joystick_index = -1; m_display_bit_depth = 16; + m_msaa = 1; + m_anisotropy = 1; m_haptic = TRUE; m_touch_scheme = 2; m_texture_load = TRUE; @@ -181,11 +184,16 @@ bool CConfigApp::ReadRegisterSettings() 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_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_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_x_res = iniparser_getint(dict, "isle:Horizontal Resolution", m_x_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); iniparser_freedict(dict); return true; @@ -259,6 +267,34 @@ bool CConfigApp::ValidateSettings() m_touch_scheme = 2; 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; } @@ -337,6 +373,8 @@ void CConfigApp::WriteRegisterSettings() const iniparser_set(dict, "isle:savepath", m_save_path.c_str()); 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:Full Screen", m_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:Horizontal Resolution", m_x_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()); #undef SetIniBool diff --git a/CONFIG/qt/config.h b/CONFIG/qt/config.h index ad3321ac..c0dcb851 100644 --- a/CONFIG/qt/config.h +++ b/CONFIG/qt/config.h @@ -62,11 +62,16 @@ class CConfigApp { int m_aspect_ratio; int m_x_res; int m_y_res; + int m_exf_x_res; + int m_exf_y_res; + float m_exf_fps; float m_frame_delta; LegoDeviceEnumerate* m_device_enumerator; MxDriver* m_driver; Direct3DDeviceInfo* m_device; int m_display_bit_depth; + int m_msaa; + int m_anisotropy; bool m_flip_surfaces; bool m_full_screen; bool m_exclusive_full_screen; diff --git a/CONFIG/qt/res/maindialog.ui b/CONFIG/qt/res/maindialog.ui index 5a0d3b31..e395159b 100644 --- a/CONFIG/qt/res/maindialog.ui +++ b/CONFIG/qt/res/maindialog.ui @@ -56,6 +56,9 @@ false + + fullscreenRadioContainer_2 + @@ -353,12 +356,18 @@ A higher setting will cause higher quality textures to be drawn regardless of di - 15 + 20 0 + + + 20 + 16777215 + + - 35 + 3.5 @@ -533,10 +542,16 @@ The game will gradually increase the number of actors until this maximum is reac - 15 + 20 0 + + + 20 + 16777215 + + 20 @@ -602,8 +617,59 @@ The game will gradually increase the number of actors until this maximum is reac General - - + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:700;">Windowed:</span> Runs in a window, the initial resolution of which is dictated by Windowed Resolution. </p><p><span style=" font-weight:700;">Fullscreen:</span> Runs in a borderless window that consumes the entire screen. </p><p><span style=" font-weight:700;">Exclusive Fullscreen:</span> Grants the app full control of the display for better performance and lower input lag. May cause slower alt-tabbing.</p></body></html> + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Windowed + + + + + + + Fullscreen + + + + + + + Exclusive Fullscreen + + + + + + + <html><head/><body><p>Maximum framerate. Values above 100fps are untested.</p></body></html> @@ -622,33 +688,6 @@ The game will gradually increase the number of actors until this maximum is reac - - - - - - Toggle fullscreen display mode. - - - Fullscreen - - - - - - - false - - - Grants the app full control of the display for better performance and lower input lag. May cause slower alt-tabbing. - - - Exclusive Fullscreen - - - - - @@ -765,17 +804,135 @@ The game will gradually increase the number of actors until this maximum is reac - - - Qt::Orientation::Vertical + + + false - - - 20 - 40 - + + Exclusive Fullscreen Resolution - + + + + + Resolution + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + MSAA + + + + + + 0 + + + 4 + + + 1 + + + Qt::Orientation::Horizontal + + + QSlider::TickPosition::TicksBothSides + + + 1 + + + + + + + + 16 + 0 + + + + 1 + + + Qt::AlignmentFlag::AlignCenter + + + + + + + + + + Anisotropic Filtering + + + + + + 0 + + + 4 + + + 1 + + + Qt::Orientation::Horizontal + + + QSlider::TickPosition::TicksBothSides + + + 1 + + + + + + + + 16 + 0 + + + + 1 + + + Qt::AlignmentFlag::AlignCenter + + + + + + + + @@ -860,7 +1017,7 @@ The game will gradually increase the number of actors until this maximum is reac Settings for Texture Loader extension. - Texture Loader Extension + Texture Loader @@ -1007,12 +1164,16 @@ The game will gradually increase the number of actors until this maximum is reac maxLoDSlider maxActorsSlider devicesList - fullscreenCheckBox - exclusiveFullscreenCheckbox + windowedRadioButton + fullscreenRadioButton + exFullscreenRadioButton framerateSpinBox aspectRatioComboBox xResSpinBox yResSpinBox + exFullResComboBox + msaaSlider + AFSlider touchComboBox rumbleCheckBox textureCheckBox diff --git a/ISLE/emscripten/events.cpp b/ISLE/emscripten/events.cpp index 5cf67e51..436c1b64 100644 --- a/ISLE/emscripten/events.cpp +++ b/ISLE/emscripten/events.cpp @@ -36,3 +36,11 @@ void Emscripten_SendPresenterProgress(MxDSAction* p_action, MxPresenter::TickleS 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); +} diff --git a/ISLE/emscripten/events.h b/ISLE/emscripten/events.h index fac59cad..a22d7b55 100644 --- a/ISLE/emscripten/events.h +++ b/ISLE/emscripten/events.h @@ -4,5 +4,6 @@ #include "mxpresenter.h" void Emscripten_SendPresenterProgress(MxDSAction* p_action, MxPresenter::TickleState p_tickleState); +void Emscripten_SendExtensionProgress(const char* p_extension, MxU32 p_progress); #endif // EMSCRIPTEN_EVENTS_H diff --git a/ISLE/emscripten/filesystem.cpp b/ISLE/emscripten/filesystem.cpp index 50cd9012..c2bfbc37 100644 --- a/ISLE/emscripten/filesystem.cpp +++ b/ISLE/emscripten/filesystem.cpp @@ -1,8 +1,10 @@ #include "filesystem.h" +#include "events.h" +#include "extensions/textureloader.h" #include "legogamestate.h" #include "misc.h" -#include "mxomni.h" +#include "mxmain.h" #include #include @@ -13,6 +15,7 @@ static backend_t opfs = nullptr; static backend_t fetchfs = nullptr; extern const char* g_files[46]; +extern const char* g_textures[120]; bool Emscripten_OPFSDisabled() { @@ -41,7 +44,7 @@ bool Emscripten_SetupConfig(const char* p_iniConfig) 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/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) { 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 (!opfs) { opfs = wasmfs_create_opfs_backend(); diff --git a/ISLE/emscripten/window.cpp b/ISLE/emscripten/window.cpp index 6766490f..fd8b144c 100644 --- a/ISLE/emscripten/window.cpp +++ b/ISLE/emscripten/window.cpp @@ -84,7 +84,8 @@ void Emscripten_ConvertEventToRenderCoordinates(SDL_Event* event) } case SDL_EVENT_FINGER_MOTION: 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 widthRatio = (g_targetWidth * scale) / g_fullWidth; const float heightRatio = (g_targetHeight * scale) / g_fullHeight; diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 024e9aea..ae6b0e68 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -185,8 +185,13 @@ IsleApp::IsleApp() m_haptic = TRUE; m_xRes = 640; m_yRes = 480; + m_exclusiveXRes = m_xRes; + m_exclusiveYRes = m_yRes; + m_exclusiveFrameRate = 60.00f; m_frameRate = 100.0f; m_exclusiveFullScreen = FALSE; + m_msaaSamples = 0; + m_anisotropic = 0.0f; } // FUNCTION: ISLE 0x4011a0 @@ -291,7 +296,7 @@ void IsleApp::SetupVideoFlags( m_videoParam.Flags().SetLacksLightSupport(!hasLightSupport); m_videoParam.Flags().SetF1bit7(param_7); m_videoParam.Flags().SetWideViewAngle(wideViewAngle); - m_videoParam.Flags().SetF2bit1(1); + m_videoParam.Flags().SetEnabled(TRUE); m_videoParam.SetDeviceName(deviceId); if (using8bit) { 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_DOWN: case SDL_EVENT_FINGER_UP: + case SDL_EVENT_FINGER_CANCELED: IDirect3DRMMiniwinDevice* device = GetD3DRMMiniwinDevice(); if (device && !device->ConvertEventToRenderCoordinates(event)) { SDL_Log("Failed to convert event coordinates: %s", SDL_GetError()); @@ -512,6 +518,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) } break; case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + case SDL_EVENT_QUIT: if (!g_closed) { delete g_isle; g_isle = NULL; @@ -777,7 +784,8 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) ); } break; - case SDL_EVENT_FINGER_UP: { + case SDL_EVENT_FINGER_UP: + case SDL_EVENT_FINGER_CANCELED: { g_mousedown = FALSE; 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; } - case SDL_EVENT_QUIT: - return SDL_APP_SUCCESS; - break; } 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"); } } - else if (event->user.type == g_legoSdlEvents.m_hitActor && g_isle->GetHaptic()) { - if (!InputManager()->HandleRumbleEvent(0.5f, 0.5f, 0.5f, 700)) { + else if (event->user.type == g_legoSdlEvents.m_gameEvent) { + 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 #ifdef __EMSCRIPTEN__ - Emscripten_HandleRumbleEvent(0.5f, 0.5f, 700); + Emscripten_HandleRumbleEvent(p_lowFrequencyRumble, p_highFrequencyRumble, p_milliseconds); #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 window = SDL_CreateWindowWithProperties(props); + SDL_SetPointerProperty(SDL_GetWindowProperties(window), ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM, &m_videoParam); if (m_exclusiveFullScreen && m_fullScreen) { SDL_DisplayMode closestMode; 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); } } @@ -1098,6 +1130,9 @@ bool IsleApp::LoadConfig() 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: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)); #ifdef EXTENSIONS @@ -1175,11 +1210,16 @@ bool IsleApp::LoadConfig() m_haptic = iniparser_getboolean(dict, "isle:Haptic", m_haptic); m_xRes = iniparser_getint(dict, "isle:Horizontal Resolution", m_xRes); 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) { 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_frameDelta = static_cast(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); if (deviceId != NULL) { diff --git a/ISLE/isleapp.h b/ISLE/isleapp.h index 4a23ea23..66e8e6e1 100644 --- a/ISLE/isleapp.h +++ b/ISLE/isleapp.h @@ -109,8 +109,13 @@ class IsleApp { MxBool m_haptic; MxS32 m_xRes; MxS32 m_yRes; + MxS32 m_exclusiveXRes; + MxS32 m_exclusiveYRes; + MxFloat m_exclusiveFrameRate; MxFloat m_frameRate; MxBool m_exclusiveFullScreen; + MxU32 m_msaaSamples; + MxFloat m_anisotropic; }; extern IsleApp* g_isle; diff --git a/ISLE/isledebug.cpp b/ISLE/isledebug.cpp index ec27004b..5b9bd590 100644 --- a/ISLE/isledebug.cpp +++ b/ISLE/isledebug.cpp @@ -46,7 +46,7 @@ class DebugViewer { if (plantManager->m_numEntries) { if (ImGui::BeginTable("Animated Entries", 4, ImGuiTableFlags_Borders)) { ImGui::TableSetupColumn("ROI Name"); - ImGui::TableSetupColumn("ROI m_unk0x100"); + ImGui::TableSetupColumn("ROI m_sharedLodList"); ImGui::TableSetupColumn("Entity Name"); ImGui::TableSetupColumn("Time"); ImGui::TableHeadersRow(); @@ -55,7 +55,7 @@ class DebugViewer { ImGui::TableNextRow(); ImGui::Text("%s", entry->m_roi->m_name); ImGui::TableNextColumn(); - ImGui::Text("%d", entry->m_roi->m_unk0x100); + ImGui::Text("%d", entry->m_roi->m_sharedLodList); ImGui::TableNextColumn(); ImGui::Text("%s", entry->m_roi->m_entity->ClassName()); ImGui::TableNextColumn(); @@ -75,7 +75,7 @@ class DebugViewer { if (buildingManager->m_numEntries) { if (ImGui::BeginTable("Animated Entries", 6, ImGuiTableFlags_Borders)) { ImGui::TableSetupColumn("ROI Name"); - ImGui::TableSetupColumn("ROI m_unk0x100"); + ImGui::TableSetupColumn("ROI m_sharedLodList"); ImGui::TableSetupColumn("Entity Name"); ImGui::TableSetupColumn("Time"); ImGui::TableSetupColumn("Y"); @@ -86,13 +86,13 @@ class DebugViewer { ImGui::TableNextRow(); ImGui::Text("%s", entry->m_roi->m_name); ImGui::TableNextColumn(); - ImGui::Text("%d", entry->m_roi->m_unk0x100); + ImGui::Text("%d", entry->m_roi->m_sharedLodList); ImGui::TableNextColumn(); ImGui::Text("%s", entry->m_roi->m_entity->ClassName()); ImGui::TableNextColumn(); ImGui::Text("%d", entry->m_time); ImGui::TableNextColumn(); - ImGui::Text("%d", entry->m_y); + ImGui::Text("%f", entry->m_y); ImGui::TableNextColumn(); ImGui::Text("%d", entry->m_muted); } @@ -135,7 +135,7 @@ class DebugViewer { ImGui::Text("unk0x70: %u", videoManager->m_unk0x70); ImGui::Text("Dither: %d", videoManager->m_dither); 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("front: %g", videoManager->m_front); ImGui::Text("cameraWidth: %g", videoManager->m_cameraWidth); diff --git a/ISLE/islefiles.cpp b/ISLE/islefiles.cpp index 6e0bb482..c6f4566d 100644 --- a/ISLE/islefiles.cpp +++ b/ISLE/islefiles.cpp @@ -46,3 +46,24 @@ const char* g_files[46] = { "/LEGO/data/WORLD.WDB", "/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" +}; diff --git a/LEGO1/lego/legoomni/include/ambulance.h b/LEGO1/lego/legoomni/include/ambulance.h index cb6a396a..4f0a0623 100644 --- a/LEGO1/lego/legoomni/include/ambulance.h +++ b/LEGO1/lego/legoomni/include/ambulance.h @@ -211,7 +211,7 @@ class Ambulance : public IslePathActor { MxS16 m_atPoliceTask; // 0x16c MxS16 m_atBeachTask; // 0x16e MxS16 m_taskState; // 0x170 - MxS16 m_unk0x172; // 0x172 + MxS16 m_enableRandomAudio; // 0x172 IsleScript::Script m_lastAction; // 0x174 IsleScript::Script m_lastAnimation; // 0x178 MxFloat m_fuel; // 0x17c diff --git a/LEGO1/lego/legoomni/include/infocenter.h b/LEGO1/lego/legoomni/include/infocenter.h index aa0befd1..2839bc88 100644 --- a/LEGO1/lego/legoomni/include/infocenter.h +++ b/LEGO1/lego/legoomni/include/infocenter.h @@ -18,6 +18,25 @@ class LegoControlManagerNotificationParam; // SIZE 0x94 class InfocenterState : public LegoState { 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() override; @@ -72,7 +91,7 @@ class InfocenterState : public LegoState { Playlist m_returnDialogue[3]; // 0x20 Playlist m_leaveDialogue[3]; // 0x44 Playlist m_bricksterDialogue; // 0x68 - MxU32 m_unk0x74; // 0x74 + MxU32 m_state; // 0x74 MxStillPresenter* m_letters[7]; // 0x78 }; diff --git a/LEGO1/lego/legoomni/include/isle.h b/LEGO1/lego/legoomni/include/isle.h index 53edd931..658c285c 100644 --- a/LEGO1/lego/legoomni/include/isle.h +++ b/LEGO1/lego/legoomni/include/isle.h @@ -150,18 +150,18 @@ class Isle : public LegoWorld { return !strcmp(p_name, Isle::ClassName()) || LegoWorld::IsA(p_name); } - MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - void ReadyWorld() override; // vtable+0x50 - void Add(MxCore* p_object) override; // vtable+0x58 - void VTable0x60() override; // vtable+0x60 - MxBool Escape() override; // vtable+0x64 - void Enable(MxBool p_enable) override; // vtable+0x68 - virtual void VTable0x6c(LegoPathActor* p_actor); // vtable+0x6c + MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 + void ReadyWorld() override; // vtable+0x50 + void Add(MxCore* p_object) override; // vtable+0x58 + void VTable0x60() override; // vtable+0x60 + MxBool Escape() override; // vtable+0x64 + void Enable(MxBool p_enable) override; // vtable+0x68 + virtual void RemoveVehicle(LegoPathActor* p_actor); // vtable+0x6c void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; } MxBool HasHelicopter() { return m_helicopter != NULL; } - void FUN_10033350(); + void SwitchToInfocenter(); friend class Act1State; @@ -175,13 +175,13 @@ class Isle : public LegoWorld { MxLong HandleTransitionEnd(); void HandleElevatorEndAction(); void UpdateGlobe(); - void FUN_10032620(); + void CheckAreaExiting(); void CreateState(); - void FUN_10032d30( + void TransitionToOverlay( IsleScript::Script p_script, JukeboxScript::Script p_music, const char* p_cameraLocation, - MxBool p_und + MxBool p_setCamera ); Act1State* m_act1state; // 0xf8 diff --git a/LEGO1/lego/legoomni/include/jetski.h b/LEGO1/lego/legoomni/include/jetski.h index 984c7751..5f29c907 100644 --- a/LEGO1/lego/legoomni/include/jetski.h +++ b/LEGO1/lego/legoomni/include/jetski.h @@ -35,7 +35,7 @@ class Jetski : public IslePathActor { void ActivateSceneActions(); - MxS16 GetUnknown0x160() { return m_jetskiDashboardStreamId; } + MxS16 GetJetskiDashboardStreamId() { return m_jetskiDashboardStreamId; } // SYNTHETIC: LEGO1 0x1007e5c0 // Jetski::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index 94bdc9fa..4b764d0b 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -304,4 +304,7 @@ class LegoAnimationManager : public MxCore { // TEMPLATE: LEGO1 0x10061750 // MxListCursor::MxListCursor +// TEMPLATE: BETA10 0x1004b5d0 +// MxListCursor::Next + #endif // LEGOANIMATIONMANAGER_H diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 802e8917..6e983144 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -2,6 +2,7 @@ #define LEGOANIMPRESENTER_H #include "legoroilist.h" +#include "legoroimaplist.h" #include "mxatom.h" #include "mxvideopresenter.h" @@ -147,14 +148,191 @@ class LegoAnimPresenter : public MxVideoPresenter { MxS16 m_unk0x9c; // 0x9c Matrix4* m_unk0xa0; // 0xa0 + // SYNTHETIC: LEGO1 0x10068650 + // LegoAnimPresenter::`scalar deleting destructor' + public: float m_unk0xa4; // 0xa4 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 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 -// SYNTHETIC: LEGO1 0x10068650 -// LegoAnimPresenter::`scalar deleting destructor' // TEMPLATE: LEGO1 0x100689c0 // map >::~map > @@ -212,6 +390,33 @@ class LegoAnimPresenter : public MxVideoPresenter { // GLOBAL: LEGO1 0x100f7688 // _Tree,map >::_Kfn,LegoAnimStructComparator,allocator >::_Nil + +// TEMPLATE: LEGO1 0x1006ddb0 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::~_Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Inc + +// TEMPLATE: LEGO1 0x1006dec0 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::erase + +// TEMPLATE: LEGO1 0x1006e310 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Erase + +// TEMPLATE: LEGO1 0x1006e350 +// Map::~Map + +// TEMPLATE: LEGO1 0x1006e3a0 +// map >::~map > + +// TEMPLATE: LEGO1 0x1006e6d0 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Dec + +// TEMPLATE: LEGO1 0x1006e720 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Insert + +// GLOBAL: LEGO1 0x100f768c +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Nil // clang-format on #endif // LEGOANIMPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legobuildingmanager.h b/LEGO1/lego/legoomni/include/legobuildingmanager.h index 4d27695c..355b9715 100644 --- a/LEGO1/lego/legoomni/include/legobuildingmanager.h +++ b/LEGO1/lego/legoomni/include/legobuildingmanager.h @@ -59,7 +59,8 @@ class LegoBuildingManager : public MxCore { // FUNCTION: LEGO1 0x1002f930 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 return "LegoBuildingManager"; } diff --git a/LEGO1/lego/legoomni/include/legocachesoundmanager.h b/LEGO1/lego/legoomni/include/legocachesoundmanager.h index 2f9f851b..642ef087 100644 --- a/LEGO1/lego/legoomni/include/legocachesoundmanager.h +++ b/LEGO1/lego/legoomni/include/legocachesoundmanager.h @@ -48,10 +48,13 @@ typedef set Set100d6b4c; typedef list List100d6b4c; // VTABLE: LEGO1 0x100d6b4c +// VTABLE: BETA10 0x101becac // SIZE 0x20 class LegoCacheSoundManager { public: + // FUNCTION: BETA10 0x100d0a60 LegoCacheSoundManager() {} + ~LegoCacheSoundManager(); virtual MxResult Tickle(); // vtable+0x00 @@ -68,6 +71,9 @@ class LegoCacheSoundManager { List100d6b4c m_list; // 0x14 }; +// SYNTHETIC: BETA10 0x100d06b0 +// LegoCacheSoundManager::`scalar deleting destructor' + // TODO: Function names subject to change. // clang-format off diff --git a/LEGO1/lego/legoomni/include/legocameracontroller.h b/LEGO1/lego/legoomni/include/legocameracontroller.h index 4dcb6c39..cf4e8f0a 100644 --- a/LEGO1/lego/legoomni/include/legocameracontroller.h +++ b/LEGO1/lego/legoomni/include/legocameracontroller.h @@ -38,17 +38,17 @@ class LegoCameraController : public LegoPointOfViewController { virtual MxResult Create(); // vtable+0x44 void SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up); - void FUN_10012290(float p_angle); - void FUN_10012320(float p_angle); - MxResult FUN_100123b0(Matrix4& p_matrix); - void FUN_100123e0(const Matrix4& p_transform, MxU32 p_und); + void RotateZ(float p_angle); + void RotateY(float p_angle); + MxResult GetPointOfView(Matrix4& p_matrix); + void TransformPointOfView(const Matrix4& p_transform, MxU32 p_multiply); Mx3DPointFloat GetWorldUp(); Mx3DPointFloat GetWorldLocation(); Mx3DPointFloat GetWorldDirection(); private: - MxMatrix m_matrix1; // 0x38 - MxMatrix m_matrix2; // 0x80 + MxMatrix m_currentTransform; // 0x38 + MxMatrix m_originalTransform; // 0x80 }; // SYNTHETIC: LEGO1 0x10011f50 diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index 9b4c5313..4443ca8a 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -48,6 +48,7 @@ struct LegoActorInfo; typedef map LegoCharacterMap; // VTABLE: LEGO1 0x100da878 +// VTABLE: BETA10 0x101bc028 // SIZE 0x24 class CustomizeAnimFileVariable : public MxVariable { public: diff --git a/LEGO1/lego/legoomni/include/legocontrolmanager.h b/LEGO1/lego/legoomni/include/legocontrolmanager.h index f962ee0c..680bef59 100644 --- a/LEGO1/lego/legoomni/include/legocontrolmanager.h +++ b/LEGO1/lego/legoomni/include/legocontrolmanager.h @@ -24,11 +24,11 @@ class LegoControlManagerNotificationParam : public LegoEventNotificationParam { void SetClickedObjectId(MxS32 p_clickedObjectId) { m_clickedObjectId = p_clickedObjectId; } 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 const char* m_clickedAtom; // 0x24 - MxS16 m_unk0x28; // 0x28 + MxS16 m_enabledChild; // 0x28 }; // SYNTHETIC: LEGO1 0x10028bf0 diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h index 28e5b47d..44d5bc27 100644 --- a/LEGO1/lego/legoomni/include/legogamestate.h +++ b/LEGO1/lego/legoomni/include/legogamestate.h @@ -30,6 +30,7 @@ struct InternationalCharacter { }; // VTABLE: LEGO1 0x100d74a8 +// VTABLE: BETA10 0x101bc4f0 // SIZE 0x30 class LegoBackgroundColor : public MxVariable { public: @@ -50,9 +51,11 @@ class LegoBackgroundColor : public MxVariable { }; // VTABLE: LEGO1 0x100d74b8 +// VTABLE: BETA10 0x101bc500 // SIZE 0x24 class LegoFullScreenMovie : public MxVariable { public: + LegoFullScreenMovie(); LegoFullScreenMovie(const char* p_key, const char* p_value); void SetValue(const char* p_option) override; // vtable+0x04 @@ -110,19 +113,19 @@ class LegoGameState { e_dunecarbuild, e_jetskibuild, e_racecarbuild, - e_unk40, + e_helicopterSpawn, e_unk41, e_unk42, - e_unk43, - e_unk44, - e_unk45, + e_dunebuggySpawn, + e_racecarSpawn, + e_jetskiSpawn, e_act2main, e_act3script, e_unk48, e_unk49, e_unk50, e_unk51, - e_unk52, + e_towTrackHookedUp, e_jukeboxw, e_jukeboxExterior, e_unk55, diff --git a/LEGO1/lego/legoomni/include/legohideanimpresenter.h b/LEGO1/lego/legoomni/include/legohideanimpresenter.h deleted file mode 100644 index b2bbb7b8..00000000 --- a/LEGO1/lego/legoomni/include/legohideanimpresenter.h +++ /dev/null @@ -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 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,map >::_Kfn,LegoHideAnimStructComparator,allocator >::~_Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Inc - -// TEMPLATE: LEGO1 0x1006dec0 -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::erase - -// TEMPLATE: LEGO1 0x1006e310 -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Erase - -// TEMPLATE: LEGO1 0x1006e350 -// Map::~Map - -// TEMPLATE: LEGO1 0x1006e3a0 -// map >::~map > - -// TEMPLATE: LEGO1 0x1006e6d0 -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Dec - -// TEMPLATE: LEGO1 0x1006e720 -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Insert - -// GLOBAL: LEGO1 0x100f768c -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Nil -// clang-format on - -#endif // LEGOHIDEANIMPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h b/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h deleted file mode 100644 index df2f872e..00000000 --- a/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h +++ /dev/null @@ -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 diff --git a/LEGO1/lego/legoomni/include/legoloopinganimpresenter.h b/LEGO1/lego/legoomni/include/legoloopinganimpresenter.h deleted file mode 100644 index 8952cbba..00000000 --- a/LEGO1/lego/legoomni/include/legoloopinganimpresenter.h +++ /dev/null @@ -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 diff --git a/LEGO1/lego/legoomni/include/legomain.h b/LEGO1/lego/legoomni/include/legomain.h index 90196e6a..c5cb23af 100644 --- a/LEGO1/lego/legoomni/include/legomain.h +++ b/LEGO1/lego/legoomni/include/legomain.h @@ -5,7 +5,7 @@ #include "lego1_export.h" #include "legoutils.h" #include "mxdsaction.h" -#include "mxomni.h" +#include "mxmain.h" #include #include @@ -114,6 +114,7 @@ class LegoOmni : public MxOmni { } // FUNCTION: LEGO1 0x10058ab0 + // FUNCTION: BETA10 0x1008f860 MxBool IsA(const char* p_name) const override // vtable+0x10 { return !strcmp(p_name, LegoOmni::ClassName()) || MxOmni::IsA(p_name); @@ -153,9 +154,14 @@ class LegoOmni : public MxOmni { // FUNCTION: BETA10 0x1009e7a0 LegoInputManager* GetInputManager() { return m_inputManager; } + // FUNCTION: BETA10 0x100e5400 LegoTextureContainer* GetTextureContainer() { return m_textureContainer; } + ViewLODListManager* GetViewLODListManager() { return m_viewLODListManager; } + + // FUNCTION: BETA10 0x100969b0 LegoWorld* GetCurrentWorld() { return m_currentWorld; } + LegoNavController* GetNavController() { return m_navController; } LegoPathActor* GetUserActor() { return m_userActor; } @@ -185,8 +191,8 @@ class LegoOmni : public MxOmni { // FUNCTION: BETA10 0x100d55c0 void SetExit(MxBool p_exit) { m_exit = p_exit; } - MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; } - void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; } + MxResult StartActionIfInitialized(MxDSAction& p_dsAction) { return m_initialized ? Start(&p_dsAction) : SUCCESS; } + void SetInitialized(MxBool p_unk0x13c) { m_initialized = p_unk0x13c; } void CloseMainWindow() { @@ -204,6 +210,7 @@ class LegoOmni : public MxOmni { MxBool IsVersion10() { return m_version10; } // SYNTHETIC: LEGO1 0x10058b30 + // SYNTHETIC: BETA10 0x1008f8d0 // LegoOmni::`scalar deleting destructor' private: @@ -227,7 +234,7 @@ class LegoOmni : public MxOmni { MxBool m_version10; public: - MxBool m_unk0x13c; // 0x13c + MxBool m_initialized; // 0x13c }; #endif // LEGOMAIN_H diff --git a/LEGO1/lego/legoomni/include/legopartpresenter.h b/LEGO1/lego/legoomni/include/legopartpresenter.h index 7ff7692d..3c3fc2f1 100644 --- a/LEGO1/lego/legoomni/include/legopartpresenter.h +++ b/LEGO1/lego/legoomni/include/legopartpresenter.h @@ -4,6 +4,7 @@ #include "lego1_export.h" #include "legonamedpartlist.h" #include "mxmediapresenter.h" +#include "viewmanager/viewlodlist.h" // VTABLE: LEGO1 0x100d4df0 // SIZE 0x54 @@ -50,10 +51,21 @@ class LegoPartPresenter : public MxMediaPresenter { MxResult Read(MxDSChunk& p_chunk); void Store(); + static void Release() + { + for (auto* lodList : g_lodLists) { + lodList->Release(); + } + + g_lodLists.clear(); + } + private: void Destroy(MxBool p_fromDestructor); LegoNamedPartList* m_parts; // 0x50 + + static vector g_lodLists; }; #endif // LEGOPARTPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legopathboundary.h b/LEGO1/lego/legoomni/include/legopathboundary.h index 2bc304f0..d3c1c4e7 100644 --- a/LEGO1/lego/legoomni/include/legopathboundary.h +++ b/LEGO1/lego/legoomni/include/legopathboundary.h @@ -31,6 +31,7 @@ typedef set LegoPathActorSet; typedef set LegoAnimPresenterSet; // VTABLE: LEGO1 0x100d8618 +// VTABLE: BETA10 0x101bdd58 // SIZE 0x74 class LegoPathBoundary : public LegoWEGEdge { public: @@ -57,6 +58,7 @@ class LegoPathBoundary : public LegoWEGEdge { LegoAnimPresenterSet& GetPresenters() { return m_presenters; } // SYNTHETIC: LEGO1 0x10047a80 + // SYNTHETIC: BETA10 0x100bd300 // LegoPathBoundary::`vector deleting destructor' private: diff --git a/LEGO1/lego/legoomni/include/legophonemepresenter.h b/LEGO1/lego/legoomni/include/legophonemepresenter.h index e470f6b7..4a6a3c05 100644 --- a/LEGO1/lego/legoomni/include/legophonemepresenter.h +++ b/LEGO1/lego/legoomni/include/legophonemepresenter.h @@ -42,9 +42,9 @@ class LegoPhonemePresenter : public MxFlcPresenter { MxS32 m_rectCount; // 0x68 LegoTextureInfo* m_textureInfo; // 0x6c - MxBool m_unk0x70; // 0x70 + MxBool m_reusedPhoneme; // 0x70 MxString m_roiName; // 0x74 - MxBool m_unk0x84; // 0x84 + MxBool m_isPartOfAnimMM; // 0x84 }; // TEMPLATE: LEGO1 0x1004eb20 diff --git a/LEGO1/lego/legoomni/include/legoplantmanager.h b/LEGO1/lego/legoomni/include/legoplantmanager.h index 3cdb5105..dc468dfd 100644 --- a/LEGO1/lego/legoomni/include/legoplantmanager.h +++ b/LEGO1/lego/legoomni/include/legoplantmanager.h @@ -32,7 +32,7 @@ class LEGO1_EXPORT LegoPlantManager : public MxCore { const char* ClassName() const override // vtable+0x0c { // 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 return "LegoPlantManager"; } diff --git a/LEGO1/lego/legoomni/include/legosoundmanager.h b/LEGO1/lego/legoomni/include/legosoundmanager.h index 9c03b06d..f503bf6e 100644 --- a/LEGO1/lego/legoomni/include/legosoundmanager.h +++ b/LEGO1/lego/legoomni/include/legosoundmanager.h @@ -17,15 +17,15 @@ class LegoSoundManager : public MxSoundManager { void Destroy() override; // vtable+0x18 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); // FUNCTION: BETA10 0x1000f350 LegoCacheSoundManager* GetCacheSoundManager() { return m_cacheSoundManager; } + // SYNTHETIC: LEGO1 0x10029920 + // SYNTHETIC: BETA10 0x100d0660 + // LegoSoundManager::`scalar deleting destructor' + private: void Init(); void Destroy(MxBool p_fromDestructor); diff --git a/LEGO1/lego/legoomni/include/legotraninfolist.h b/LEGO1/lego/legoomni/include/legotraninfolist.h index 06cd2558..0bfe4bd8 100644 --- a/LEGO1/lego/legoomni/include/legotraninfolist.h +++ b/LEGO1/lego/legoomni/include/legotraninfolist.h @@ -28,9 +28,11 @@ class LegoTranInfoList : public MxPtrList { // class MxPtrListCursor // VTABLE: LEGO1 0x100d8d20 +// VTABLE: BETA10 0x101bad70 // SIZE 0x10 class LegoTranInfoListCursor : public MxPtrListCursor { public: + // FUNCTION: BETA10 0x100496d0 LegoTranInfoListCursor(LegoTranInfoList* p_list) : MxPtrListCursor(p_list) {} }; @@ -62,9 +64,14 @@ class LegoTranInfoListCursor : public MxPtrListCursor { // MxPtrList::`scalar deleting destructor' // SYNTHETIC: LEGO1 0x100612f0 +// SYNTHETIC: BETA10 0x100498c0 // LegoTranInfoListCursor::`scalar deleting destructor' +// SYNTHETIC: BETA10 0x10049770 +// MxPtrListCursor::MxPtrListCursor + // FUNCTION: LEGO1 0x10061360 +// FUNCTION: BETA10 0x10049910 // MxPtrListCursor::~MxPtrListCursor // SYNTHETIC: LEGO1 0x100613b0 @@ -77,6 +84,7 @@ class LegoTranInfoListCursor : public MxPtrListCursor { // MxListCursor::~MxListCursor // FUNCTION: LEGO1 0x100614e0 +// FUNCTION: BETA10 0x10049ab0 // LegoTranInfoListCursor::~LegoTranInfoListCursor #endif // LEGOTRANINFOLIST_H diff --git a/LEGO1/lego/legoomni/include/legoutils.h b/LEGO1/lego/legoomni/include/legoutils.h index b29a336c..849662df 100644 --- a/LEGO1/lego/legoomni/include/legoutils.h +++ b/LEGO1/lego/legoomni/include/legoutils.h @@ -32,6 +32,14 @@ enum Cursor { e_cursorNone }; +enum GameEvent { + e_hitActor, + e_skeletonKick, + e_raceFinished, + e_badEnding, + e_goodEnding +}; + class BoundingSphere; class MxAtomId; class LegoEntity; @@ -71,7 +79,7 @@ LegoNamedTexture* ReadNamedTexture(LegoStorage* p_storage); void WriteDefaultTexture(LegoStorage* p_storage, const char* p_name); void WriteNamedTexture(LegoStorage* p_storage, LegoNamedTexture* p_namedTexture); void LoadFromNamedTexture(LegoNamedTexture* p_namedTexture); -void HitActorEvent(); +void EmitGameEvent(GameEvent p_event); // FUNCTION: BETA10 0x100260a0 inline void StartIsleAction(IsleScript::Script p_objectId) diff --git a/LEGO1/lego/legoomni/include/legovariables.h b/LEGO1/lego/legoomni/include/legovariables.h index 9447a5f9..873ef34c 100644 --- a/LEGO1/lego/legoomni/include/legovariables.h +++ b/LEGO1/lego/legoomni/include/legovariables.h @@ -17,41 +17,60 @@ extern const char* g_varVISIBILITY; extern const char* g_varCAMERALOCATION; extern const char* g_varCURSOR; extern const char* g_varWHOAMI; +extern const char* g_varDEBUG; // VTABLE: LEGO1 0x100d86c8 +// VTABLE: BETA10 0x101bc980 // SIZE 0x24 class VisibilityVariable : public MxVariable { public: + // FUNCTION: BETA10 0x10093470 VisibilityVariable() { m_key = g_varVISIBILITY; } void SetValue(const char* p_value) override; // vtable+0x04 }; // VTABLE: LEGO1 0x100d86b8 +// VTABLE: BETA10 0x101bc990 // SIZE 0x24 class CameraLocationVariable : public MxVariable { public: + // FUNCTION: BETA10 0x10093510 CameraLocationVariable() { m_key = g_varCAMERALOCATION; } void SetValue(const char* p_value) override; // vtable+0x04 }; // VTABLE: LEGO1 0x100d86a8 +// VTABLE: BETA10 0x101bc9a0 // SIZE 0x24 class CursorVariable : public MxVariable { public: + // FUNCTION: BETA10 0x100935b0 CursorVariable() { m_key = g_varCURSOR; } void SetValue(const char* p_value) override; // vtable+0x04 }; // VTABLE: LEGO1 0x100d8698 +// VTABLE: BETA10 0x101bc9b0 // SIZE 0x24 class WhoAmIVariable : public MxVariable { public: + // FUNCTION: BETA10 0x10093650 WhoAmIVariable() { m_key = g_varWHOAMI; } 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 diff --git a/LEGO1/lego/legoomni/include/legovideomanager.h b/LEGO1/lego/legoomni/include/legovideomanager.h index ff5f9ae3..b6ad3866 100644 --- a/LEGO1/lego/legoomni/include/legovideomanager.h +++ b/LEGO1/lego/legoomni/include/legovideomanager.h @@ -27,6 +27,7 @@ class Renderer; } // VTABLE: LEGO1 0x100d9c88 +// VTABLE: BETA10 0x101bef08 // SIZE 0x590 class LegoVideoManager : public MxVideoManager { public: @@ -49,6 +50,7 @@ class LegoVideoManager : public MxVideoManager { virtual MxPresenter* GetPresenterAt(MxS32 p_x, MxS32 p_y); // vtable+0x38 // FUNCTION: LEGO1 0x1007ab10 + // FUNCTION: BETA10 0x100d8010 virtual LegoPhonemeList* GetPhonemeList() { return m_phonemeRefList; } // vtable+0x3c 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; } + // SYNTHETIC: LEGO1 0x1007ab20 + // SYNTHETIC: BETA10 0x100d8040 + // LegoVideoManager::`scalar deleting destructor' + private: MxResult CreateDirect3D(); MxResult ConfigureD3DRM(); @@ -135,7 +141,4 @@ class LegoVideoManager : public MxVideoManager { friend class DebugViewer; }; -// SYNTHETIC: LEGO1 0x1007ab20 -// LegoVideoManager::`scalar deleting destructor' - #endif // LEGOVIDEOMANAGER_H diff --git a/LEGO1/lego/legoomni/include/legoworldlist.h b/LEGO1/lego/legoomni/include/legoworldlist.h index 6d1006b0..6f92540c 100644 --- a/LEGO1/lego/legoomni/include/legoworldlist.h +++ b/LEGO1/lego/legoomni/include/legoworldlist.h @@ -16,12 +16,15 @@ class LegoWorld; // class MxPtrList // VTABLE: LEGO1 0x100d8680 +// VTABLE: BETA10 0x101bc900 // SIZE 0x18 class LegoWorldList : public MxPtrList { public: + // FUNCTION: BETA10 0x10092ce0 LegoWorldList(MxBool p_ownership = FALSE) : MxPtrList(p_ownership) {} // 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 // SYNTHETIC: LEGO1 0x10059a00 diff --git a/LEGO1/lego/legoomni/include/misc.h b/LEGO1/lego/legoomni/include/misc.h index 1df9fe37..8e294343 100644 --- a/LEGO1/lego/legoomni/include/misc.h +++ b/LEGO1/lego/legoomni/include/misc.h @@ -53,7 +53,7 @@ void Disable(MxBool p_disable, MxU16 p_flags); LegoROI* FindROI(const char* p_name); void SetROIVisible(const char* p_name, MxBool p_visible); void SetUserActor(LegoPathActor* p_userActor); -MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction); +MxResult StartActionIfInitialized(MxDSAction& p_dsAction); void DeleteAction(); LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid); MxDSAction& GetCurrentAction(); diff --git a/LEGO1/lego/legoomni/include/pizza.h b/LEGO1/lego/legoomni/include/pizza.h index 5fa91df1..99e2ca6c 100644 --- a/LEGO1/lego/legoomni/include/pizza.h +++ b/LEGO1/lego/legoomni/include/pizza.h @@ -39,7 +39,7 @@ class PizzaMissionState : public LegoState { m_unk0x08 = 1; m_finishTimes = p_finishTimes; m_startTime = INT_MIN; - m_unk0x14 = 1; + m_counter = 1; m_score = LegoState::e_grey; m_hiScore = LegoState::e_grey; m_actions = p_actions; @@ -54,7 +54,7 @@ class PizzaMissionState : public LegoState { m_unk0x08 = p_mission.m_unk0x08; m_finishTimes = p_mission.m_finishTimes; 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_hiScore = p_mission.m_hiScore; m_actions = p_mission.m_actions; @@ -102,12 +102,24 @@ class PizzaMissionState : public LegoState { undefined m_unk0x08; // 0x08 MxLong* m_finishTimes; // 0x0c MxLong m_startTime; // 0x10 - MxS16 m_unk0x14; // 0x14 + MxS16 m_counter; // 0x14 MxS16 m_score; // 0x16 MxS16 m_hiScore; // 0x18 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(); // FUNCTION: LEGO1 0x10039290 @@ -142,7 +154,7 @@ class PizzaMissionState : public LegoState { MxS16 GetActorState(); PizzeriaState* m_pizzeriaState; // 0x08 - undefined4 m_unk0x0c; // 0x0c + MxU32 m_state; // 0x0c Mission m_missions[5]; // 0x10 MxU32 m_playedAction; // 0xb0 @@ -189,8 +201,8 @@ class Pizza : public IsleActor { MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param) override; // vtable+0x80 void CreateState(); - void FUN_10038220(IsleScript::Script p_objectId); - void FUN_100382b0(); + void Start(IsleScript::Script p_objectId); + void Reset(); void StopActions(); void PlayAction(MxU32 p_objectId, MxBool p_param7); @@ -207,7 +219,7 @@ class Pizza : public IsleActor { IsleScript::Script m_speechAction; // 0x8c MxLong m_startTime; // 0x90 MxLong m_duration; // 0x94 - MxBool m_unk0x98; // 0x98 + MxBool m_playedLocationAnimation; // 0x98 }; #endif // PIZZA_H diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index 726f3838..799b196a 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -631,7 +631,7 @@ MxU32 Act2Actor::FUN_10019700(MxFloat p_param) MxFloat time = p_param - (m_unk0x2c - m_shootAnim->GetDuration()); 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; diff --git a/LEGO1/lego/legoomni/src/actors/act3actors.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp index 89bdc5fc..2926466f 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actors.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -4,9 +4,9 @@ #include "act3ammo.h" #include "anim/legoanim.h" #include "define.h" +#include "legoanimpresenter.h" #include "legobuildingmanager.h" #include "legocachesoundmanager.h" -#include "legolocomotionanimpresenter.h" #include "legopathedgecontainer.h" #include "legoplantmanager.h" #include "legoplants.h" @@ -639,7 +639,7 @@ void Act3Brickster::Animate(float p_time) float time = p_time - (m_unk0x50 - m_shootAnim->GetDuration()); 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()); 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; LegoTreeNode* node = m_unk0x34->GetAnimTreePtr()->GetRoot(); - LegoROI::FUN_100a8e80(node, mat, duration, m_unk0x34->GetROIMap()); + LegoROI::ApplyAnimationTransformation(node, mat, duration, m_unk0x34->GetROIMap()); } else { roiMap[1] = m_unk0x38; diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp index 23c9164d..0d2b89cc 100644 --- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp +++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp @@ -44,7 +44,7 @@ Ambulance::Ambulance() m_atBeachTask = 0; m_taskState = Ambulance::e_none; m_lastAction = IsleScript::c_noneIsle; - m_unk0x172 = 0; + m_enableRandomAudio = 0; m_lastAnimation = IsleScript::c_noneIsle; m_fuel = 1.0; } @@ -176,7 +176,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param) m_state->m_state = AmbulanceMissionState::e_enteredAmbulance; CurrentWorld()->PlaceActor(UserActor()); HandleClick(); - m_unk0x172 = 0; + m_enableRandomAudio = 0; 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) { @@ -201,7 +201,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param) CurrentWorld()->PlaceActor(UserActor()); HandleClick(); SpawnPlayer(LegoGameState::e_pizzeriaExterior, TRUE, 0); - m_unk0x172 = 0; + m_enableRandomAudio = 0; TickleManager()->RegisterClient(this, 40000); if (m_atPoliceTask != 0) { @@ -225,7 +225,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param) CurrentWorld()->PlaceActor(UserActor()); HandleClick(); SpawnPlayer(LegoGameState::e_policeExited, TRUE, 0); - m_unk0x172 = 0; + m_enableRandomAudio = 0; TickleManager()->RegisterClient(this, 40000); if (m_atBeachTask != 0) { @@ -440,7 +440,7 @@ MxLong Ambulance::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_AmbulanceArms_Ctl: Exit(); @@ -457,7 +457,7 @@ MxLong Ambulance::HandleControl(LegoControlManagerNotificationParam& p_param) case IsleScript::c_AmbulanceHorn_Ctl: MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "AmbulanceHorn_Sound"); - presenter->Enable(p_param.m_unk0x28); + presenter->Enable(p_param.m_enabledChild); break; } } @@ -516,8 +516,8 @@ void Ambulance::ActivateSceneActions() // FUNCTION: BETA10 0x100237df MxResult Ambulance::Tickle() { - if (m_unk0x172 == 0) { - m_unk0x172 = 1; + if (m_enableRandomAudio == 0) { + m_enableRandomAudio = 1; } else if (m_lastAction == IsleScript::c_noneIsle) { IsleScript::Script objectId; diff --git a/LEGO1/lego/legoomni/src/actors/bike.cpp b/LEGO1/lego/legoomni/src/actors/bike.cpp index fa9bedcb..fbdce39e 100644 --- a/LEGO1/lego/legoomni/src/actors/bike.cpp +++ b/LEGO1/lego/legoomni/src/actors/bike.cpp @@ -81,7 +81,7 @@ MxLong Bike::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_BikeArms_Ctl: Exit(); @@ -97,7 +97,7 @@ MxLong Bike::HandleControl(LegoControlManagerNotificationParam& p_param) case IsleScript::c_BikeHorn_Ctl: MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "BikeHorn_Sound"); - presenter->Enable(p_param.m_unk0x28); + presenter->Enable(p_param.m_enabledChild); break; } } diff --git a/LEGO1/lego/legoomni/src/actors/buildings.cpp b/LEGO1/lego/legoomni/src/actors/buildings.cpp index b9e736c4..989f1d99 100644 --- a/LEGO1/lego/legoomni/src/actors/buildings.cpp +++ b/LEGO1/lego/legoomni/src/actors/buildings.cpp @@ -49,7 +49,7 @@ MxLong InfoCenterEntity::HandleClick(LegoEventNotificationParam& p_param) } Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle); - isle->FUN_10033350(); + isle->SwitchToInfocenter(); isle->SetDestLocation(LegoGameState::Area::e_infomain); Act1State* act1state = (Act1State*) GameState()->GetState("Act1State"); diff --git a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp index 0c398393..5b701c46 100644 --- a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp +++ b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp @@ -124,7 +124,7 @@ MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_DuneCarArms_Ctl: Exit(); @@ -140,7 +140,7 @@ MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param) case IsleScript::c_DuneCarHorn_Ctl: MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "DuneCarHorn_Sound"); - presenter->Enable(p_param.m_unk0x28); + presenter->Enable(p_param.m_enabledChild); break; } } diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 46353585..fc2addb3 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -82,7 +82,7 @@ void Helicopter::Exit() if (GameState()->GetCurrentAct() == LegoGameState::e_act1) { SpawnPlayer( - LegoGameState::e_unk40, + LegoGameState::e_helicopterSpawn, TRUE, IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3 ); @@ -189,7 +189,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param) break; } - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { MxU32 isPizza = FALSE; switch (p_param.m_clickedObjectId) { @@ -426,7 +426,7 @@ void Helicopter::Animate(float p_time) v2 *= f2; v2 += v1; - m_world->GetCameraController()->FUN_100123e0(mat, 0); + m_world->GetCameraController()->TransformPointOfView(mat, 0); } else { 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 Vector3 vec6((const float*) m_unk0x1a8[3]); // locala0 // esp+0x28 - m_world->GetCameraController()->FUN_100123b0(local48); + m_world->GetCameraController()->GetPointOfView(local48); m_unk0x1a8.SetIdentity(); local90 = p_matrix; diff --git a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp index 9d5a3a22..d366761e 100644 --- a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp @@ -355,7 +355,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_PoliceStation_Music ); g_spawnLocations[16] = SpawnLocation( - LegoGameState::e_unk40, + LegoGameState::e_helicopterSpawn, g_isleScript, 0, "edg02_51", @@ -379,7 +379,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_noneJukebox ); g_spawnLocations[18] = SpawnLocation( - LegoGameState::e_unk43, + LegoGameState::e_dunebuggySpawn, g_isleScript, 0, "edg02_35", @@ -391,7 +391,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_noneJukebox ); g_spawnLocations[19] = SpawnLocation( - LegoGameState::e_unk44, + LegoGameState::e_racecarSpawn, g_isleScript, 0, "EDG03_01", @@ -403,7 +403,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_noneJukebox ); g_spawnLocations[20] = SpawnLocation( - LegoGameState::e_unk45, + LegoGameState::e_jetskiSpawn, g_isleScript, 0, "edg10_70", @@ -475,7 +475,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_noneJukebox ); g_spawnLocations[26] = SpawnLocation( - LegoGameState::e_unk52, + LegoGameState::e_towTrackHookedUp, g_isleScript, 0, "edg02_19", diff --git a/LEGO1/lego/legoomni/src/actors/jetski.cpp b/LEGO1/lego/legoomni/src/actors/jetski.cpp index 43c8040c..cdde06ee 100644 --- a/LEGO1/lego/legoomni/src/actors/jetski.cpp +++ b/LEGO1/lego/legoomni/src/actors/jetski.cpp @@ -69,7 +69,7 @@ void Jetski::Animate(float p_time) // FUNCTION: LEGO1 0x1007e6f0 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(); GameState()->m_currentArea = LegoGameState::e_jetski; RemoveFromWorld(); @@ -139,7 +139,7 @@ void Jetski::RemoveFromWorld() // FUNCTION: LEGO1 0x1007e8e0 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) { case IsleScript::c_JetskiArms_Ctl: Exit(); diff --git a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp index 9d17be8d..3a4229b3 100644 --- a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp +++ b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp @@ -117,7 +117,7 @@ MxLong Motocycle::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_MotoBikeArms_Ctl: Exit(); diff --git a/LEGO1/lego/legoomni/src/actors/pizza.cpp b/LEGO1/lego/legoomni/src/actors/pizza.cpp index 422cf87f..291969cf 100644 --- a/LEGO1/lego/legoomni/src/actors/pizza.cpp +++ b/LEGO1/lego/legoomni/src/actors/pizza.cpp @@ -137,7 +137,7 @@ Pizza::Pizza() m_skateBoard = NULL; m_act1state = NULL; m_speechAction = IsleScript::c_noneIsle; - m_unk0x98 = FALSE; + m_playedLocationAnimation = FALSE; m_startTime = INT_MIN; } @@ -177,11 +177,11 @@ void Pizza::CreateState() // FUNCTION: LEGO1 0x10038220 // FUNCTION: BETA10 0x100edb81 -void Pizza::FUN_10038220(IsleScript::Script p_objectId) +void Pizza::Start(IsleScript::Script p_objectId) { AnimationManager()->FUN_10064740(NULL); 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_mission->m_startTime = INT_MIN; g_isleFlags &= ~Isle::c_playMusic; @@ -193,22 +193,22 @@ void Pizza::FUN_10038220(IsleScript::Script p_objectId) // FUNCTION: LEGO1 0x100382b0 // 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) { InvokeAction(Extra::e_stop, *g_isleScript, m_speechAction, NULL); } m_act1state->m_state = Act1State::e_none; - m_state->m_unk0x0c = 0; + m_state->m_state = PizzaMissionState::e_none; UserActor()->SetActorState(LegoPathActor::c_initial); g_isleFlags |= Isle::c_playMusic; AnimationManager()->EnableCamAnims(TRUE); AnimationManager()->FUN_1005f6d0(TRUE); m_mission->m_startTime = INT_MIN; m_mission = NULL; - m_unk0x98 = FALSE; + m_playedLocationAnimation = FALSE; m_speechAction = IsleScript::c_noneIsle; BackgroundAudioManager()->RaiseVolume(); TickleManager()->UnregisterClient(this); @@ -237,14 +237,14 @@ void Pizza::StopActions() // FUNCTION: BETA10 0x100edd10 MxLong Pizza::HandleClick() { - if (m_state->m_unk0x0c == 1) { - m_state->m_unk0x0c = 2; + if (m_state->m_state == PizzaMissionState::e_introduction) { + m_state->m_state = PizzaMissionState::e_waitAcceptingQuest; m_mission->m_startTime = Timer()->GetTime(); TickleManager()->RegisterClient(this, 200); 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; if (m_skateBoard == NULL) { @@ -266,7 +266,7 @@ MxLong Pizza::HandleClick() } PlayAction(action, TRUE); - m_state->m_unk0x0c = 3; + m_state->m_state = PizzaMissionState::e_started; PlayMusic(JukeboxScript::c_PizzaMission_Music); return 1; } @@ -278,12 +278,12 @@ MxLong Pizza::HandleClick() // FUNCTION: BETA10 0x100ede53 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; if (p_param.GetTrigger() == LegoPathStruct::c_s && p_param.GetData() == 0x12e && GameState()->GetActorId() == LegoActor::c_pepper) { - m_state->m_unk0x0c = 5; + m_state->m_state = PizzaMissionState::e_arrivedAtDestination; m_state->SetPlayedAction(SndanimScript::c_TRS302_OpenJailDoor); if (time < m_mission->GetRedFinishTime()) { @@ -348,20 +348,20 @@ MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param) break; } - m_state->m_unk0x0c = 5; + m_state->m_state = PizzaMissionState::e_arrivedAtDestination; PlayAction(action, TRUE); MxTrace("Pizza mission: ending\n"); } else if (p_param.GetTrigger() == LegoPathStruct::c_w) { if (p_param.GetData() == 0x15e && GameState()->GetActorId() == LegoActor::c_pepper) { - if (!m_unk0x98) { - m_unk0x98 = TRUE; + if (!m_playedLocationAnimation) { + m_playedLocationAnimation = TRUE; InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_pns050p1_RunAnim, NULL); } } - else if (p_param.GetData() == 0x15f && GameState()->GetActorId() == LegoActor::c_papa && !m_unk0x98) { - m_unk0x98 = TRUE; + else if (p_param.GetData() == 0x15f && GameState()->GetActorId() == LegoActor::c_papa && !m_playedLocationAnimation) { + m_playedLocationAnimation = TRUE; 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_state->m_unk0x0c == 4) { + if (m_state->m_state == PizzaMissionState::e_delivering) { assert(m_mission); if (time > m_mission->m_startTime + m_mission->GetTimeoutTime()) { StopActions(); m_mission->UpdateScore(LegoState::e_grey); - FUN_100382b0(); + Reset(); BackgroundAudioManager()->LowerVolume(); InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_Avo917In_PlayWav, NULL); 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); if (Timer()->GetTime() > m_mission->m_startTime + 5000) { @@ -429,7 +429,7 @@ MxResult Pizza::Tickle() m_skateBoard->EnableScenePresentation(FALSE); TickleManager()->UnregisterClient(this); m_mission->UpdateScore(LegoState::e_grey); - m_state->m_unk0x0c = 9; + m_state->m_state = PizzaMissionState::e_timeoutAcceptingQuest; AnimationManager()->FUN_1005f6d0(TRUE); PlayAction(m_mission->GetUnknownFinishAction(), TRUE); MxTrace("Pizza mission: timeout, declining\n"); @@ -452,16 +452,16 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param) return 1; } - switch (m_state->m_unk0x0c) { - case 1: + switch (m_state->m_state) { + case PizzaMissionState::e_introduction: if (m_state->GetPlayedAction() == objectId) { - m_state->m_unk0x0c = 2; + m_state->m_state = PizzaMissionState::e_waitAcceptingQuest; m_mission->m_startTime = Timer()->GetTime(); TickleManager()->RegisterClient(this, 200); MxTrace("Pizza mission: proposed\n"); } break; - case 3: + case PizzaMissionState::e_started: if (m_state->GetPlayedAction() == objectId) { 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); } - m_state->m_unk0x0c = 4; + m_state->m_state = PizzaMissionState::e_delivering; m_state->SetPlayedAction(IsleScript::c_noneIsle); UserActor()->SetActorState(LegoPathActor::c_initial); m_skateBoard->SetPizzaVisible(TRUE); @@ -489,7 +489,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param) result = 1; } break; - case 5: + case PizzaMissionState::e_arrivedAtDestination: if (m_state->GetPlayedAction() == objectId) { StopActions(); @@ -497,26 +497,26 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param) IsleScript::Script action = IsleScript::c_noneIsle; if (!((Isle*) CurrentWorld())->HasHelicopter()) { - switch (m_mission->m_unk0x14) { + switch (m_mission->m_counter) { case 1: action = IsleScript::c_pja126br_RunAnim; - m_mission->m_unk0x14++; - m_state->m_unk0x0c = 6; + m_mission->m_counter++; + m_state->m_state = PizzaMissionState::e_suggestHelicopter; MxTrace("Pizza mission: succeeds\n"); break; case 2: action = IsleScript::c_pja129br_RunAnim; m_startTime = Timer()->GetTime(); m_duration = 500; - m_mission->m_unk0x14++; - m_state->m_unk0x0c = 6; + m_mission->m_counter++; + m_state->m_state = PizzaMissionState::e_suggestHelicopter; MxTrace("Pizza mission: succeeds\n"); break; case 3: action = IsleScript::c_pja131br_RunAnim; m_startTime = Timer()->GetTime(); m_duration = 500; - m_state->m_unk0x0c = 6; + m_state->m_state = PizzaMissionState::e_suggestHelicopter; break; } } @@ -524,7 +524,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param) action = IsleScript::c_pja132br_RunAnim; m_startTime = Timer()->GetTime(); m_duration = 2300; - m_state->m_unk0x0c = 8; + m_state->m_state = PizzaMissionState::e_transitionToAct2; InputManager()->DisableInputProcessing(); InputManager()->SetUnknown336(TRUE); MxTrace("Pizza mission: go to Act2\n"); @@ -533,42 +533,42 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param) PlayAction(action, TRUE); } else { - FUN_100382b0(); - m_state->m_unk0x0c = 0; + Reset(); + m_state->m_state = PizzaMissionState::e_none; m_state->SetPlayedAction(IsleScript::c_noneIsle); } } break; - case 6: + case PizzaMissionState::e_suggestHelicopter: if (m_state->GetPlayedAction() == objectId) { 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_duration = 700; } else if (objectId == IsleScript::c_pja129br_RunAnim) { - PlayAction(IsleScript::c_pja130br_RunAnim, TRUE); + PlayAction(IsleScript::c_pja130br_RunAnim, TRUE); // build helicopter! } else { - FUN_100382b0(); - m_state->m_unk0x0c = 0; + Reset(); + m_state->m_state = PizzaMissionState::e_none; m_state->SetPlayedAction(IsleScript::c_noneIsle); } } break; - case 8: + case PizzaMissionState::e_transitionToAct2: if (m_state->GetPlayedAction() == objectId) { 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; TickleManager()->UnregisterClient(this); ((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_act2main); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); } break; - case 9: + case PizzaMissionState::e_timeoutAcceptingQuest: if (m_state->GetPlayedAction() == objectId) { - FUN_100382b0(); + Reset(); } break; } @@ -594,7 +594,7 @@ void Pizza::PlayAction(MxU32 p_objectId, MxBool p_param7) // FUNCTION: BETA10 0x100eea25 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[1] = Mission(LegoActor::c_mama, 2, g_mamaFinishTimes, g_mamaActions, 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()) { for (MxS16 i = 0; i < 5; i++) { 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_hiScore); } @@ -621,7 +621,7 @@ MxResult PizzaMissionState::Serialize(LegoStorage* p_storage) else if (p_storage->IsWriteMode()) { for (MxS16 i = 0; i < 5; i++) { 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_hiScore); } diff --git a/LEGO1/lego/legoomni/src/actors/pizzeria.cpp b/LEGO1/lego/legoomni/src/actors/pizzeria.cpp index 3b5f8923..b9aa6edc 100644 --- a/LEGO1/lego/legoomni/src/actors/pizzeria.cpp +++ b/LEGO1/lego/legoomni/src/actors/pizzeria.cpp @@ -69,7 +69,7 @@ void Pizzeria::CreateState() // FUNCTION: BETA10 0x100efc91 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()->IsA("SkateBoard")) { ((IslePathActor*) UserActor())->Exit(); @@ -79,7 +79,7 @@ MxLong Pizzeria::HandleClick() AnimationManager()->FUN_10061010(FALSE); 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; diff --git a/LEGO1/lego/legoomni/src/actors/skateboard.cpp b/LEGO1/lego/legoomni/src/actors/skateboard.cpp index d47b2178..70d1be72 100644 --- a/LEGO1/lego/legoomni/src/actors/skateboard.cpp +++ b/LEGO1/lego/legoomni/src/actors/skateboard.cpp @@ -59,7 +59,7 @@ void SkateBoard::Exit() if (m_act1state->m_state == Act1State::e_pizza) { Pizza* pizza = (Pizza*) CurrentWorld()->Find(*g_isleScript, IsleScript::c_Pizza_Actor); pizza->StopActions(); - pizza->FUN_100382b0(); + pizza->Reset(); m_pizzaVisible = FALSE; } @@ -110,7 +110,7 @@ MxLong SkateBoard::HandleControl(LegoControlManagerNotificationParam& p_param) { 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(); GameState()->m_currentArea = LegoGameState::Area::e_vehicleExited; result = 1; diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp index 462905d4..bf6b29bc 100644 --- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp +++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp @@ -434,7 +434,7 @@ MxLong TowTrack::HandleClick() } if (m_state->m_state == TowTrackMissionState::e_hookedUp) { - SpawnPlayer(LegoGameState::e_unk52, TRUE, 0); + SpawnPlayer(LegoGameState::e_towTrackHookedUp, TRUE, 0); FindROI("rcred")->SetVisibility(FALSE); } else { @@ -485,7 +485,7 @@ MxLong TowTrack::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_TowTrackArms_Ctl: Exit(); @@ -501,7 +501,7 @@ MxLong TowTrack::HandleControl(LegoControlManagerNotificationParam& p_param) break; case IsleScript::c_TowHorn_Ctl: MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "TowHorn_Sound"); - presenter->Enable(p_param.m_unk0x28); + presenter->Enable(p_param.m_enabledChild); break; } } diff --git a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp index 572864dc..a6224ccf 100644 --- a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp +++ b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp @@ -5,7 +5,7 @@ #include "legosoundmanager.h" #include "legovideomanager.h" #include "misc.h" -#include "mxomni.h" +#include "mxmain.h" #include diff --git a/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp b/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp index 38a418d4..684b498f 100644 --- a/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp +++ b/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp @@ -2,7 +2,7 @@ #include "mxcompositepresenter.h" #include "mxdsaction.h" -#include "mxomni.h" +#include "mxmain.h" DECOMP_SIZE_ASSERT(Lego3DWavePresenter, 0xa0) diff --git a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp index 34be4519..cd235b61 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp @@ -7,6 +7,7 @@ DECOMP_SIZE_ASSERT(LegoCacheSoundEntry, 0x08) DECOMP_SIZE_ASSERT(LegoCacheSoundManager, 0x20) // FUNCTION: LEGO1 0x1003cf20 +// STUB: BETA10 0x100d0700 LegoCacheSoundManager::~LegoCacheSoundManager() { LegoCacheSound* sound; @@ -28,6 +29,7 @@ LegoCacheSoundManager::~LegoCacheSoundManager() } // FUNCTION: LEGO1 0x1003d050 +// STUB: BETA10 0x100652f0 MxResult LegoCacheSoundManager::Tickle() { #ifdef COMPAT_MODE diff --git a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp index 864659da..8203a0df 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp @@ -2,7 +2,7 @@ #include "legosoundmanager.h" #include "misc.h" -#include "mxomni.h" +#include "mxmain.h" #include diff --git a/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp b/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp index 8adb79df..a9b60d66 100644 --- a/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp +++ b/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp @@ -98,7 +98,7 @@ void LegoLoadCacheSoundPresenter::DoneTickle() // FUNCTION: LEGO1 0x10018700 MxResult LegoLoadCacheSoundPresenter::PutData() { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_currentTickleState == e_done) { m_cacheSound = SoundManager()->GetCacheSoundManager()->ManageSoundEntry(m_cacheSound); diff --git a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp index 1d53e64d..fb25945f 100644 --- a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp @@ -2,31 +2,35 @@ #include "legocachesoundmanager.h" #include "mxautolock.h" -#include "mxomni.h" +#include "mxmain.h" #include DECOMP_SIZE_ASSERT(LegoSoundManager, 0x44) // FUNCTION: LEGO1 0x100298a0 +// FUNCTION: BETA10 0x100cffb0 LegoSoundManager::LegoSoundManager() { Init(); } // FUNCTION: LEGO1 0x10029940 +// FUNCTION: BETA10 0x100d0027 LegoSoundManager::~LegoSoundManager() { Destroy(TRUE); } // FUNCTION: LEGO1 0x100299a0 +// FUNCTION: BETA10 0x100d0099 void LegoSoundManager::Init() { m_cacheSoundManager = NULL; } // FUNCTION: LEGO1 0x100299b0 +// FUNCTION: BETA10 0x100d00c9 void LegoSoundManager::Destroy(MxBool p_fromDestructor) { delete m_cacheSoundManager; @@ -41,17 +45,19 @@ void LegoSoundManager::Destroy(MxBool p_fromDestructor) // FUNCTION: BETA10 0x100d0129 MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) { - MxBool locked = FALSE; MxResult result = FAILURE; + MxBool locked = FALSE; - if (MxSoundManager::Create(10, FALSE) == SUCCESS) { - m_criticalSection.Enter(); - locked = TRUE; - m_cacheSoundManager = new LegoCacheSoundManager; - assert(m_cacheSoundManager); - result = SUCCESS; + if (MxSoundManager::Create(10, FALSE) != SUCCESS) { + goto done; } + ENTER(m_criticalSection); + locked = TRUE; + m_cacheSoundManager = new LegoCacheSoundManager; + assert(m_cacheSoundManager); + result = SUCCESS; + done: if (result != SUCCESS) { Destroy(); diff --git a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp index 8b90d39b..567dd882 100644 --- a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp @@ -15,6 +15,7 @@ DECOMP_SIZE_ASSERT(MxBackgroundAudioManager, 0x150) // FUNCTION: LEGO1 0x1007ea90 +// FUNCTION: BETA10 0x100e8530 MxBackgroundAudioManager::MxBackgroundAudioManager() { NotificationManager()->Register(this); diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index da309660..ab456f39 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -956,7 +956,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param; assert(m_buildState); - if (param->m_unk0x28) { + if (param->m_enabledChild) { switch (param->m_clickedObjectId) { // The enum values are all identical between CopterScript, DunecarScript, JetskiScript, and RacecarScript case CopterScript::c_Info_Ctl: @@ -1012,7 +1012,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) case CopterScript::c_Platform_Ctl: FUN_10024f50(); m_unk0xf8 = c_unknown8; - m_unk0xfc = param->m_unk0x28; + m_unk0xfc = param->m_enabledChild; result = 1; break; default: @@ -1054,7 +1054,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param; assert(m_buildState); - if (param->m_unk0x28) { + if (param->m_enabledChild) { switch (param->m_clickedObjectId) { case CopterScript::c_Info_Ctl: m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_selected); @@ -1116,7 +1116,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) case CopterScript::c_Platform_Ctl: FUN_10024f50(); m_unk0xf8 = c_unknown8; - m_unk0xfc = param->m_unk0x28; + m_unk0xfc = param->m_enabledChild; result = 1; break; default: @@ -1233,7 +1233,7 @@ undefined4 LegoCarBuild::FUN_10024c20(MxNotificationParam* p_param) jukeboxScript = JukeboxScript::c_RaceCarBuild_Music; } - m_unk0x338 = SoundManager()->FUN_100aebd0(*g_jukeboxScript, jukeboxScript); + m_unk0x338 = SoundManager()->FindPresenter(*g_jukeboxScript, jukeboxScript); if (m_unk0x338) { BackgroundAudioManager()->SetPendingPresenter(m_unk0x338, 5, MxPresenter::e_repeating); diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 665c6459..90ea44c6 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -11,7 +11,6 @@ #include "legoentitylist.h" #include "legoextraactor.h" #include "legogamestate.h" -#include "legolocomotionanimpresenter.h" #include "legomain.h" #include "legonavcontroller.h" #include "legoroilist.h" @@ -20,6 +19,7 @@ #include "legoworld.h" #include "misc.h" #include "mxbackgroundaudiomanager.h" +#include "mxdebug.h" #include "mxmisc.h" #include "mxnotificationmanager.h" #include "mxticklemanager.h" @@ -1021,7 +1021,7 @@ MxResult LegoAnimationManager::FUN_100605e0( action.SetUnknown24(-1); action.AppendExtra(strlen(buf) + 1, buf); - if (StartActionIfUnknown0x13c(action) == SUCCESS) { + if (StartActionIfInitialized(action) == SUCCESS) { BackgroundAudioManager()->LowerVolume(); tranInfo->m_flags |= LegoTranInfo::c_bit2; animInfo.m_unk0x22++; @@ -1088,7 +1088,7 @@ MxResult LegoAnimationManager::FUN_100609f0(MxU32 p_objectId, MxMatrix* p_matrix action.SetUnknown24(-1); action.AppendExtra(strlen(buf) + 1, buf); - if (StartActionIfUnknown0x13c(action) == SUCCESS) { + if (StartActionIfInitialized(action) == SUCCESS) { BackgroundAudioManager()->LowerVolume(); info->m_flags |= LegoTranInfo::c_bit2; 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; } @@ -1155,7 +1155,7 @@ MxResult LegoAnimationManager::FUN_10060dc0( MxResult result = FAILURE; MxBool found = FALSE; - if (!Lego()->m_unk0x13c) { + if (!Lego()->m_initialized) { return SUCCESS; } @@ -1192,7 +1192,7 @@ MxResult LegoAnimationManager::FUN_10060dc0( // FUNCTION: BETA10 0x1004206c 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); if (location != NULL) { @@ -1231,12 +1231,10 @@ void LegoAnimationManager::CameraTriggerFire(LegoPathActor* p_actor, MxBool, MxU } } -// FUNCTION: LEGO1 0x10061010 +#ifdef BETA10 // FUNCTION: BETA10 0x100422cc void LegoAnimationManager::FUN_10061010(MxBool p_und) { - MxBool unk0x39 = FALSE; - FUN_10064b50(-1); if (m_tranInfoList != NULL) { @@ -1244,17 +1242,47 @@ void LegoAnimationManager::FUN_10061010(MxBool p_und) LegoTranInfo* tranInfo; while (cursor.Next(tranInfo)) { - if (tranInfo->m_presenter != NULL) { - // TODO: Match - MxU32 flags = tranInfo->m_flags; + if (tranInfo->m_unk0x14 && tranInfo->m_location != -1) { + MxTrace("Releasing user from %d\n", tranInfo->m_objectId); + 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) { - LegoAnim* anim; - - if (tranInfo->m_presenter->GetPresenter() != NULL && - (anim = tranInfo->m_presenter->GetPresenter()->GetAnimation()) != NULL && - anim->GetCamAnim() != NULL) { - if (flags & LegoTranInfo::c_bit2) { + if (tranInfo->m_presenter->GetPresenter() && + tranInfo->m_presenter->GetPresenter()->GetAnimation() && + tranInfo->m_presenter->GetPresenter()->GetAnimation()->GetCamAnim()) { + if (tranInfo->m_flags & LegoTranInfo::c_bit2) { BackgroundAudioManager()->RaiseVolume(); tranInfo->m_flags &= ~LegoTranInfo::c_bit2; } @@ -1263,37 +1291,43 @@ void LegoAnimationManager::FUN_10061010(MxBool p_und) tranInfo->m_unk0x14 = FALSE; } else { + MxTrace("Releasing user from %d\n", tranInfo->m_objectId); + // LINE: LEGO1 0x10061137 tranInfo->m_presenter->FUN_1004b8c0(); + animRunning = TRUE; tranInfo->m_unk0x14 = FALSE; - unk0x39 = TRUE; } } else { - if (flags & LegoTranInfo::c_bit2) { + if (tranInfo->m_flags & LegoTranInfo::c_bit2) { + // LINE: LEGO1 0x10061150 BackgroundAudioManager()->RaiseVolume(); tranInfo->m_flags &= ~LegoTranInfo::c_bit2; } + MxTrace("Stopping %d\n", tranInfo->m_objectId); tranInfo->m_presenter->FUN_1004b840(); } } else { if (m_tranInfoList2 != NULL) { LegoTranInfoListCursor cursor(m_tranInfoList2); - 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); } } - unk0x39 = TRUE; + animRunning = TRUE; } } } - m_animRunning = unk0x39; + m_animRunning = animRunning; m_unk0x404 = Timer()->GetTime(); } +#endif // FUNCTION: LEGO1 0x10061530 void LegoAnimationManager::FUN_10061530() @@ -2784,7 +2818,11 @@ MxResult LegoAnimationManager::FUN_10064880(const char* p_name, MxS32 p_unk0x0c, // FUNCTION: BETA10 0x10045daf 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; m_unk0x430 = TRUE; m_unk0x42c = p_tranInfo; @@ -2805,11 +2843,13 @@ void LegoAnimationManager::FUN_100648f0(LegoTranInfo* p_tranInfo, MxLong p_unk0x if (location != NULL) { CalcLocalTransform(location->m_position, location->m_direction, location->m_up, m_unk0x484); m_unk0x4cc.SetStartEnd(m_unk0x43c, m_unk0x484); +#ifndef BETA10 m_unk0x4cc.NormalizeDirection(); } else { p_tranInfo->m_flags &= ~LegoTranInfo::c_bit1; m_unk0x430 = FALSE; +#endif } Mx3DPointFloat vec; diff --git a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp index ca6c2412..af32a238 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp @@ -425,6 +425,21 @@ MxBool LegoAnimMMPresenter::FUN_1004b6b0(MxLong p_time) // FUNCTION: BETA10 0x1004ce18 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(); LegoPathActor* actor = UserActor(); @@ -455,9 +470,13 @@ MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time) m_world->PlaceActor(actor); } +#ifdef BETA10 + actor->VTable0xa8(); +#else if (m_tranInfo->m_unk0x29) { actor->VTable0xa8(); } +#endif } actor->SetActorState(LegoPathActor::c_initial); @@ -491,9 +510,11 @@ void LegoAnimMMPresenter::FUN_1004b840() FUN_1004b6d0(0); EndAction(); +#ifndef BETA10 if (action != NULL) { Streamer()->FUN_100b98f0(action); } +#endif } // FUNCTION: LEGO1 0x1004b8b0 diff --git a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp index 8dae5d61..f82747bf 100644 --- a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp @@ -47,6 +47,7 @@ MxU8 g_buildingInfoDownshift[16] = { }; // GLOBAL: LEGO1 0x100f3478 +// GLOBAL: BETA10 0x101e4d78 LegoBuildingInfo g_buildingInfoInit[16] = { { NULL, "infocen", @@ -236,8 +237,11 @@ void LegoBuildingManager::configureLegoBuildingManager(MxS32 p_buildingManagerCo } // FUNCTION: LEGO1 0x1002f8c0 +// FUNCTION: BETA10 0x10063a30 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(); } @@ -247,6 +251,7 @@ LegoBuildingManager::~LegoBuildingManager() delete[] g_customizeAnimFile; } +// // FUNCTION: BETA10 0x10063a30 -- see the constructor // FUNCTION: LEGO1 0x1002f9d0 void LegoBuildingManager::Init() { diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index adf442eb..180b8eec 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -1092,6 +1092,7 @@ LegoROI* LegoCharacterManager::FUN_10085a80(const char* p_name, const char* p_lo } // FUNCTION: LEGO1 0x10085aa0 +// FUNCTION: BETA10 0x1007703d CustomizeAnimFileVariable::CustomizeAnimFileVariable(const char* p_key) { m_key = p_key; @@ -1099,6 +1100,7 @@ CustomizeAnimFileVariable::CustomizeAnimFileVariable(const char* p_key) } // FUNCTION: LEGO1 0x10085b50 +// FUNCTION: BETA10 0x100770c8 void CustomizeAnimFileVariable::SetValue(const char* p_value) { // STRING: LEGO1 0x100fc4f4 diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index 4ba42020..c97a5abc 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -1179,28 +1179,28 @@ void LegoGameState::Init() Helicopter* copter = (Helicopter*) isle->Find(*g_copterScript, CopterScript::c_Helicopter_Actor); if (copter) { isle->RemoveActor(copter); - isle->VTable0x6c(copter); + isle->RemoveVehicle(copter); delete copter; } DuneBuggy* dunebuggy = (DuneBuggy*) isle->Find(*g_dunecarScript, DunecarScript::c_DuneBugy_Actor); if (dunebuggy) { isle->RemoveActor(dunebuggy); - isle->VTable0x6c(dunebuggy); + isle->RemoveVehicle(dunebuggy); delete dunebuggy; } Jetski* jetski = (Jetski*) isle->Find(*g_jetskiScript, JetskiScript::c_Jetski_Actor); if (jetski) { isle->RemoveActor(jetski); - isle->VTable0x6c(jetski); + isle->RemoveVehicle(jetski); delete jetski; } RaceCar* racecar = (RaceCar*) isle->Find(*g_racecarScript, RacecarScript::c_RaceCar_Actor); if (racecar) { isle->RemoveActor(racecar); - isle->VTable0x6c(racecar); + isle->RemoveVehicle(racecar); delete racecar; } } @@ -1349,6 +1349,11 @@ void LegoBackgroundColor::SetLightColor() SetLightColor(convertedR, convertedG, convertedB); } +// FUNCTION: BETA10 0x10086a87 +LegoFullScreenMovie::LegoFullScreenMovie() +{ +} + // FUNCTION: LEGO1 0x1003c500 // FUNCTION: BETA10 0x10086af6 LegoFullScreenMovie::LegoFullScreenMovie(const char* p_key, const char* p_value) diff --git a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp index 68a3b35a..b8514020 100644 --- a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp +++ b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp @@ -10,7 +10,7 @@ #include "legoentity.h" #include "legopathactor.h" // The below header inclusions should be sound. -#include "legoloopinganimpresenter.h" +#include "legoanimpresenter.h" #include "mxcompositemediapresenter.h" #include "legoactorpresenter.h" #include "legomodelpresenter.h" @@ -71,10 +71,7 @@ #include "legoentity.h" #include "legoentitypresenter.h" #include "legoflctexturepresenter.h" -#include "legohideanimpresenter.h" #include "legoloadcachesoundpresenter.h" -#include "legolocomotionanimpresenter.h" -#include "legoloopinganimpresenter.h" #include "legometerpresenter.h" #include "legomodelpresenter.h" #include "legopalettepresenter.h" diff --git a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp index a67f7e08..206d03ff 100644 --- a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp @@ -60,8 +60,11 @@ char* LegoPlantManager::g_customizeAnimFile = NULL; LegoPlantInfo g_plantInfo[81]; // FUNCTION: LEGO1 0x10026220 +// FUNCTION: BETA10 0x100c4f90 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(); } @@ -72,12 +75,10 @@ LegoPlantManager::~LegoPlantManager() delete[] g_customizeAnimFile; } +// // FUNCTION: BETA10 0x100c4f90 -- see the constructor // FUNCTION: LEGO1 0x10026330 -// FUNCTION: BETA10 0x100c4f90 void LegoPlantManager::Init() { - // In BETA10 this appears to be LegoPlantManager::LegoPlantManager() - for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) { g_plantInfo[i] = g_plantInfoInit[i]; } diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index 46d9b4d0..fdc6755a 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -784,9 +784,10 @@ void LoadFromNamedTexture(LegoNamedTexture* p_namedTexture) } } -void HitActorEvent() +void EmitGameEvent(GameEvent p_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); } diff --git a/LEGO1/lego/legoomni/src/common/legovariables.cpp b/LEGO1/lego/legoomni/src/common/legovariables.cpp index 8269dfde..5d2d6cdb 100644 --- a/LEGO1/lego/legoomni/src/common/legovariables.cpp +++ b/LEGO1/lego/legoomni/src/common/legovariables.cpp @@ -6,6 +6,7 @@ #include "legonavcontroller.h" #include "legovideomanager.h" #include "misc.h" +#include "mxdebug.h" #include "roi/legoroi.h" #include @@ -103,6 +104,10 @@ const char* g_nick = "Nick"; // STRING: LEGO1 0x100f39e0 const char* g_laura = "Laura"; +// GLOBAL: BETA10 0x101f6ce4 +// STRING: BETA10 0x101f6d54 +const char* g_varDEBUG = "DEBUG"; + // FUNCTION: LEGO1 0x10037d00 // FUNCTION: BETA10 0x100d5620 void VisibilityVariable::SetValue(const char* p_value) @@ -132,6 +137,7 @@ void VisibilityVariable::SetValue(const char* p_value) } // FUNCTION: LEGO1 0x10037d80 +// FUNCTION: BETA10 0x100d56ee void CameraLocationVariable::SetValue(const char* p_value) { char buffer[256]; @@ -139,22 +145,25 @@ void CameraLocationVariable::SetValue(const char* p_value) strcpy(buffer, p_value); - char* location = strtok(buffer, ","); - NavController()->UpdateLocation(location); + char* token = strtok(buffer, ","); + assert(token); + NavController()->UpdateLocation(token); - location = strtok(NULL, ","); - if (location) { - MxFloat pov = (MxFloat) atof(location); + token = strtok(NULL, ","); + if (token) { + MxFloat pov = (MxFloat) atof(token); VideoManager()->Get3DManager()->SetFrustrum(pov, 0.1f, 250.0f); } } // FUNCTION: LEGO1 0x10037e30 +// FUNCTION: BETA10 0x100d57e2 void CursorVariable::SetValue(const char* p_value) { } // FUNCTION: LEGO1 0x10037e40 +// FUNCTION: BETA10 0x100d57fa void WhoAmIVariable::SetValue(const char* p_value) { MxVariable::SetValue(p_value); @@ -175,3 +184,10 @@ void WhoAmIVariable::SetValue(const char* p_value) GameState()->SetActorId(LegoActor::c_laura); } } + +// FUNCTION: BETA10 0x100d58fa +void DebugVariable::SetValue(const char* p_value) +{ + MxVariable::SetValue(p_value); + MxTrace("%s\n", p_value); +} diff --git a/LEGO1/lego/legoomni/src/common/misc.cpp b/LEGO1/lego/legoomni/src/common/misc.cpp index 6b231b56..ade3e874 100644 --- a/LEGO1/lego/legoomni/src/common/misc.cpp +++ b/LEGO1/lego/legoomni/src/common/misc.cpp @@ -127,8 +127,10 @@ LegoBuildingManager* BuildingManager() } // FUNCTION: LEGO1 0x10015800 +// FUNCTION: BETA10 0x100e4bb7 LegoTextureContainer* TextureContainer() { + assert(LegoOmni::GetInstance()); return LegoOmni::GetInstance()->GetTextureContainer(); } @@ -172,9 +174,9 @@ void SetUserActor(LegoPathActor* p_userActor) // FUNCTION: LEGO1 0x10015890 // 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 diff --git a/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp b/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp index 04437877..7c6a788d 100644 --- a/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp @@ -27,6 +27,7 @@ MxCompositeMediaPresenter::~MxCompositeMediaPresenter() } // FUNCTION: LEGO1 0x10074090 +// FUNCTION: BETA10 0x100e9d37 MxResult MxCompositeMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) { AUTOLOCK(m_criticalSection); diff --git a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp index 16e72fbb..79bcb6cf 100644 --- a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp @@ -80,17 +80,14 @@ MxBool MxControlPresenter::CheckButtonDown(MxS32 p_x, MxS32 p_y, MxPresenter* p_ { assert(p_presenter); MxVideoPresenter* presenter = dynamic_cast(p_presenter); - if (!presenter) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Invalid presenter"); - return FALSE; - } + assert(presenter); if (m_style == e_map) { MxStillPresenter* map = (MxStillPresenter*) m_list.front(); assert(map && map->IsA("MxStillPresenter")); if (presenter == map || map->GetDisplayZ() < presenter->GetDisplayZ()) { - if (map->VTable0x7c()) { + if (map->HasFrameBitmapOrAlpha()) { MxRect32 rect(0, 0, map->GetWidth() - 1, map->GetHeight() - 1); rect += map->GetLocation(); @@ -160,7 +157,7 @@ MxBool MxControlPresenter::Notify(LegoControlManagerNotificationParam* p_param, p_param->SetClickedAtom(m_action->GetAtomId().GetInternal()); UpdateEnabledChild(0); p_param->SetNotification(c_notificationControl); - p_param->SetUnknown0x28(m_enabledChild); + p_param->SetEnabledChild(m_enabledChild); return TRUE; } break; @@ -170,7 +167,7 @@ MxBool MxControlPresenter::Notify(LegoControlManagerNotificationParam* p_param, p_param->SetClickedAtom(m_action->GetAtomId().GetInternal()); UpdateEnabledChild(m_stateOrCellIndex); p_param->SetNotification(c_notificationControl); - p_param->SetUnknown0x28(m_enabledChild); + p_param->SetEnabledChild(m_enabledChild); return TRUE; } break; diff --git a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp index 7431033e..7e3d9294 100644 --- a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp @@ -22,6 +22,7 @@ MxTransitionManager::TransitionType g_transitionManagerConfig = MxTransitionMana RECT g_fullScreenRect = {0, 0, 640, 480}; // FUNCTION: LEGO1 0x1004b8d0 +// FUNCTION: BETA10 0x100ec2c0 MxTransitionManager::MxTransitionManager() { m_animationTimer = 0; diff --git a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp index 7851a52a..ffd2adc3 100644 --- a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp +++ b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp @@ -14,6 +14,7 @@ DECOMP_SIZE_ASSERT(LegoControlManagerNotificationParam, 0x2c) DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x20) // FUNCTION: LEGO1 0x10028520 +// STUB: BETA10 0x1008ae50 LegoControlManager::LegoControlManager() { m_presenterList = NULL; diff --git a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp index 3e977d5b..cac7d66a 100644 --- a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp @@ -124,28 +124,28 @@ void LegoCameraController::OnMouseMove(MxU8 p_modifier, MxPoint32 p_point) // FUNCTION: LEGO1 0x10012260 void LegoCameraController::SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up) { - CalcLocalTransform(p_at, p_dir, p_up, m_matrix1); - m_matrix2 = m_matrix1; + CalcLocalTransform(p_at, p_dir, p_up, m_currentTransform); + m_originalTransform = m_currentTransform; } // FUNCTION: LEGO1 0x10012290 // FUNCTION: BETA10 0x10068c34 -void LegoCameraController::FUN_10012290(float p_angle) +void LegoCameraController::RotateZ(float p_angle) { - m_matrix1 = m_matrix2; - m_matrix1.RotateZ(p_angle); + m_currentTransform = m_originalTransform; + m_currentTransform.RotateZ(p_angle); } // FUNCTION: LEGO1 0x10012320 // FUNCTION: BETA10 0x10068c73 -void LegoCameraController::FUN_10012320(float p_angle) +void LegoCameraController::RotateY(float p_angle) { - m_matrix1 = m_matrix2; - m_matrix1.RotateY(p_angle); + m_currentTransform = m_originalTransform; + m_currentTransform.RotateY(p_angle); } // FUNCTION: LEGO1 0x100123b0 -MxResult LegoCameraController::FUN_100123b0(Matrix4& p_matrix) +MxResult LegoCameraController::GetPointOfView(Matrix4& p_matrix) { if (m_lego3DView) { ViewROI* pov = m_lego3DView->GetPointOfView(); @@ -160,7 +160,7 @@ MxResult LegoCameraController::FUN_100123b0(Matrix4& p_matrix) // FUNCTION: LEGO1 0x100123e0 // 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) { ViewROI* pov = m_lego3DView->GetPointOfView(); @@ -168,14 +168,14 @@ void LegoCameraController::FUN_100123e0(const Matrix4& p_transform, MxU32 p_und) if (pov != NULL) { MxMatrix mat; - if (p_und) { - MXM4(mat, m_matrix1, p_transform); + if (p_multiply) { + MXM4(mat, m_currentTransform, p_transform); } else { mat = p_transform; } - ((TimeROI*) pov)->FUN_100a9b40(mat, Timer()->GetTime()); + ((TimeROI*) pov)->CalculateWorldVelocity(mat, Timer()->GetTime()); pov->WrappedSetLocal2WorldWithWorldDataUpdate(mat); m_lego3DView->Moved(*pov); diff --git a/LEGO1/lego/legoomni/src/entity/legoentity.cpp b/LEGO1/lego/legoomni/src/entity/legoentity.cpp index cce17c18..927d8125 100644 --- a/LEGO1/lego/legoomni/src/entity/legoentity.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoentity.cpp @@ -197,7 +197,7 @@ void LegoEntity::FUN_10010c30() LegoWorld* world = CurrentWorld(); if (m_cameraFlag && world && world->GetCameraController() && m_roi) { - world->GetCameraController()->FUN_100123e0(m_roi->GetLocal2World(), 1); + world->GetCameraController()->TransformPointOfView(m_roi->GetLocal2World(), 1); } } diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp index 4308717a..8ad9b428 100644 --- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp @@ -555,7 +555,7 @@ MxResult LegoNavController::ProcessJoystickInput(MxBool& p_und) LegoWorld* world = CurrentWorld(); if (world && world->GetCameraController()) { - world->GetCameraController()->FUN_10012320(DTOR(povPosition)); + world->GetCameraController()->RotateY(DTOR(povPosition)); p_und = TRUE; } } @@ -672,10 +672,10 @@ MxLong LegoNavController::Notify(MxParam& p_param) InfocenterState* state = (InfocenterState*) GameState()->GetState("InfocenterState"); assert(state); - if (state != NULL && state->m_unk0x74 != 8 && currentWorld->Escape()) { + if (state != NULL && state->m_state != InfocenterState::e_exitQueried && currentWorld->Escape()) { BackgroundAudioManager()->Stop(); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); - state->m_unk0x74 = 8; + state->m_state = InfocenterState::e_exitQueried; } } break; @@ -902,7 +902,7 @@ MxLong LegoNavController::Notify(MxParam& p_param) break; case SDLK_A: if (g_animationCalcStep == 1) { - Lego()->m_unk0x13c = TRUE; + Lego()->m_initialized = TRUE; AnimationManager()->FUN_10060570(TRUE); g_animationCalcStep = 0; } diff --git a/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp index 7541e98b..fc823c60 100644 --- a/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp @@ -153,7 +153,7 @@ MxResult LegoPointOfViewController::Tickle() MxMatrix mat; CalcLocalTransform(newPos, newDir, pov->GetWorldUp(), mat); - ((TimeROI*) pov)->FUN_100a9b40(mat, Timer()->GetTime()); + ((TimeROI*) pov)->CalculateWorldVelocity(mat, Timer()->GetTime()); pov->WrappedSetLocal2WorldWithWorldDataUpdate(mat); m_lego3DView->Moved(*pov); diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index b638f1e3..1ba828cb 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -9,7 +9,6 @@ #include "legocontrolmanager.h" #include "legogamestate.h" #include "legoinputmanager.h" -#include "legolocomotionanimpresenter.h" #include "legonavcontroller.h" #include "legoplantmanager.h" #include "legosoundmanager.h" @@ -288,6 +287,7 @@ MxResult LegoWorld::PlaceActor( } // FUNCTION: LEGO1 0x1001fa70 +// FUNCTION: BETA10 0x100da328 MxResult LegoWorld::PlaceActor(LegoPathActor* p_actor) { LegoPathControllerListCursor cursor(&m_pathControllerList); @@ -303,6 +303,7 @@ MxResult LegoWorld::PlaceActor(LegoPathActor* p_actor) } // FUNCTION: LEGO1 0x1001fb70 +// FUNCTION: BETA10 0x100da3f1 MxResult LegoWorld::PlaceActor( LegoPathActor* p_actor, LegoAnimPresenter* p_presenter, diff --git a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp index b3cfc365..abf6c32a 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp @@ -260,8 +260,12 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world) ModelDbPart* part; while (cursor.Next(part)) { - if (GetViewLODListManager()->Lookup(part->m_roiName.GetData()) == NULL && - LoadWorldPart(*part, wdbFile) != SUCCESS) { + ViewLODList* lodList = GetViewLODListManager()->Lookup(part->m_roiName.GetData()); + if (lodList) { + lodList->Release(); + } + + if (lodList == NULL && LoadWorldPart(*part, wdbFile) != SUCCESS) { return FAILURE; } } diff --git a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp index f7fef27e..39a97cc0 100644 --- a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp +++ b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp @@ -28,6 +28,7 @@ const char* g_clickedAtom = NULL; MxBool g_unk0x100f67b8 = TRUE; // FUNCTION: LEGO1 0x1005b790 +// STUB: BETA10 0x10088a8e LegoInputManager::LegoInputManager() { m_keyboardNotifyList = NULL; @@ -55,11 +56,13 @@ LegoInputManager::~LegoInputManager() } // FUNCTION: LEGO1 0x1005b960 +// STUB: BETA10 0x10088c9c MxResult LegoInputManager::Create(HWND p_hwnd) { MxResult result = SUCCESS; m_controlManager = new LegoControlManager; + assert(m_controlManager); if (!m_keyboardNotifyList) { m_keyboardNotifyList = new LegoNotifyList; @@ -612,6 +615,7 @@ MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touc case e_arrowKeys: switch (p_event->type) { case SDL_EVENT_FINGER_UP: + case SDL_EVENT_FINGER_CANCELED: m_touchFlags.erase(event.fingerID); break; case SDL_EVENT_FINGER_DOWN: @@ -647,6 +651,7 @@ MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touc } break; case SDL_EVENT_FINGER_UP: + case SDL_EVENT_FINGER_CANCELED: if (event.fingerID == g_finger) { g_finger = 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_DOWN: case SDL_EVENT_FINGER_UP: + case SDL_EVENT_FINGER_CANCELED: m_lastInputMethod = SDL_TouchID_v{p_event->tfinger.touchID}; break; } diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index 0c515a1d..4a2da536 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -41,6 +41,7 @@ DECOMP_SIZE_ASSERT(LegoWorldList, 0x18) DECOMP_SIZE_ASSERT(LegoWorldListCursor, 0x10) // GLOBAL: LEGO1 0x100f6718 +// GLOBAL: BETA10 0x101ee748 // STRING: LEGO1 0x100f6710 const char* g_current = "current"; @@ -51,12 +52,14 @@ LegoOmni::LegoOmni() } // FUNCTION: LEGO1 0x10058b50 +// FUNCTION: BETA10 0x1008d128 LegoOmni::~LegoOmni() { Destroy(); } // FUNCTION: LEGO1 0x10058bd0 +// FUNCTION: BETA10 0x1008d1b4 void LegoOmni::Init() { MxOmni::Init(); @@ -74,12 +77,13 @@ void LegoOmni::Init() m_animationManager = NULL; m_buildingManager = NULL; m_bkgAudioManager = NULL; - m_unk0x13c = TRUE; + m_initialized = TRUE; m_transitionManager = NULL; m_version10 = FALSE; } // FUNCTION: LEGO1 0x10058c30 +// STUB: BETA10 0x1008d299 void LegoOmni::Destroy() { AUTOLOCK(m_criticalSection); @@ -122,6 +126,8 @@ void LegoOmni::Destroy() m_textureContainer = NULL; } + LegoPartPresenter::Release(); + if (m_viewLODListManager) { delete m_viewLODListManager; m_viewLODListManager = NULL; @@ -155,13 +161,19 @@ void LegoOmni::Destroy() MxOmni::Destroy(); } +#ifdef BETA10 +// FUNCTION: BETA10 0x100d4e5e +void EmptyFunction(int p_unknown) +{ +} +#endif + // FUNCTION: LEGO1 0x10058e70 // FUNCTION: BETA10 0x1008d6bf MxResult LegoOmni::Create(MxOmniCreateParam& p_param) { MxResult result = FAILURE; AUTOLOCK(m_criticalSection); - HWND hWnd = NULL; p_param.CreateFlags().CreateObjectFactory(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"); goto done; } - + // LINE: BETA10 0x1008d7fa if (!(m_objectFactory = new LegoObjectFactory())) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoObjectFactory"); goto done; } - + // LINE: BETA10 0x1008d882 if (!(m_soundManager = new LegoSoundManager()) || m_soundManager->Create(10, 0) != SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoSoundManager"); delete m_soundManager; m_soundManager = NULL; goto done; } - + // LINE: BETA10 0x1008d990 if (!(m_videoManager = new LegoVideoManager()) || m_videoManager->Create(p_param.GetVideoParam(), 100, 0) != SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoVideoManager"); @@ -197,24 +209,51 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param) m_videoManager = NULL; goto done; } - + // LINE: BETA10 0x1008daa7 if (!(m_inputManager = new LegoInputManager()) || m_inputManager->Create(p_param.GetWindowHandle()) != SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoInputManager"); delete m_inputManager; m_inputManager = NULL; goto done; } - + // LINE: BETA10 0x1008dbdb m_viewLODListManager = new ViewLODListManager(); + + // LINE: BETA10 0x1008dc32 m_textureContainer = new LegoTextureContainer(); + +#ifndef BETA10 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(); m_characterManager = new LegoCharacterManager(); + m_plantManager = new LegoPlantManager(); + // LINE: BETA10 0x1008ddca m_animationManager = new LegoAnimationManager(); + m_buildingManager = new LegoBuildingManager(); + // LINE: BETA10 0x1008de7b m_gameState = new LegoGameState(); + // LINE: BETA10 0x1008ded5 m_worldList = new LegoWorldList(TRUE); if (!m_viewLODListManager || !m_textureContainer || !m_worldList || !m_characterManager || !m_plantManager || @@ -228,33 +267,51 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param) goto done; } - MxVariable* variable; - - if (!(variable = new VisibilityVariable())) { + MxVariable *visibilityVar, *cameraLocationVar, *cursorVar, *whoAmIVar, *debugVar; + // LINE: BETA10 0x1008dfbd + visibilityVar = new VisibilityVariable(); + if (!visibilityVar) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create VisibilityVariable"); 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"); 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"); 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"); 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(); + +#ifndef BETA10 IslePathActor::RegisterSpawnLocations(); result = RegisterWorlds(); @@ -262,30 +319,41 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create RegisterWorlds"); 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"); 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"); - 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: return result; + // LINE: BETA10 0x1008e35d } // FUNCTION: LEGO1 0x1005a5f0 @@ -400,6 +468,7 @@ LegoWorld* LegoOmni::FindWorld(const MxAtomId& p_atom, MxS32 p_entityid) } // FUNCTION: LEGO1 0x1005b1d0 +// STUB: BETA10 0x1008e93e void LegoOmni::DeleteObject(MxDSAction& p_dsAction) { if (p_dsAction.GetAtomId().GetInternal() != NULL) { @@ -452,15 +521,16 @@ LegoROI* LegoOmni::FindROI(const char* p_name) } // FUNCTION: LEGO1 0x1005b2f0 +// FUNCTION: BETA10 0x1008eb66 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)) { world = FindWorld(MxAtomId(p_id, e_lowerCase2), p_entityId); } else { - world = this->m_currentWorld; + world = GetCurrentWorld(); } if (world != NULL) { @@ -471,14 +541,17 @@ MxEntity* LegoOmni::AddToWorld(const char* p_id, MxS32 p_entityId, MxPresenter* } // FUNCTION: LEGO1 0x1005b3a0 +// FUNCTION: BETA10 0x1008ec27 void LegoOmni::NotifyCurrentEntity(const MxNotificationParam& p_param) { - if (m_currentWorld) { - NotificationManager()->Send(m_currentWorld, p_param); + LegoWorld* currentWorld = GetCurrentWorld(); + if (currentWorld) { + NotificationManager()->Send(currentWorld, p_param); } } // FUNCTION: LEGO1 0x1005b3c0 +// FUNCTION: BETA10 0x1008ec72 MxBool LegoOmni::DoesEntityExist(MxDSAction& p_dsAction) { if (MxOmni::DoesEntityExist(p_dsAction)) { @@ -584,12 +657,19 @@ void LegoOmni::CreateBackgroundAudio() } // FUNCTION: LEGO1 0x1005b580 +// FUNCTION: BETA10 0x1008f7e0 MxResult LegoOmni::Start(MxDSAction* 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.SetObjectId(p_dsAction->GetObjectId()); this->m_action.SetUnknown24(p_dsAction->GetUnknown24()); +#endif return result; } diff --git a/LEGO1/lego/legoomni/src/main/scripts.cpp b/LEGO1/lego/legoomni/src/main/scripts.cpp index 9aaa34d8..58eccfb3 100644 --- a/LEGO1/lego/legoomni/src/main/scripts.cpp +++ b/LEGO1/lego/legoomni/src/main/scripts.cpp @@ -91,6 +91,7 @@ MxAtomId* g_creditsScript = NULL; MxAtomId* g_nocdSourceName = NULL; // FUNCTION: LEGO1 0x100528e0 +// STUB: BETA10 0x100f6133 void CreateScripts() { g_copterScript = new MxAtomId("\\lego\\scripts\\build\\copter", e_lowerCase2); diff --git a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp index 182945d5..0a1e6d98 100644 --- a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp @@ -2,7 +2,7 @@ #include "anim/legoanim.h" #include "define.h" -#include "legolocomotionanimpresenter.h" +#include "legoanimpresenter.h" #include "legopathboundary.h" #include "legoworld.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++) { - LegoROI::FUN_100a8e80(n->GetChild(j), p_transform, p_und, roiMap); + LegoROI::ApplyAnimationTransformation(n->GetChild(j), p_transform, p_und, roiMap); } if (m_cameraFlag) { diff --git a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp index 7f640326..04c551d0 100644 --- a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp @@ -1,8 +1,8 @@ #include "legoextraactor.h" #include "anim/legoanim.h" +#include "legoanimpresenter.h" #include "legocachesoundmanager.h" -#include "legolocomotionanimpresenter.h" #include "legosoundmanager.h" #include "legoworld.h" #include "misc.h" @@ -235,7 +235,9 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) assert(m_roi); assert(SoundManager()->GetCacheSoundManager()); SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE); - HitActorEvent(); + if (p_actor->GetUserNavFlag()) { + EmitGameEvent(e_hitActor); + } m_scheduledTime = Timer()->GetTime() + m_disAnim->GetDuration(); m_prevWorldSpeed = GetWorldSpeed(); VTable0xc4(); @@ -249,7 +251,9 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) LegoROI* roi = GetROI(); assert(roi); SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE); - HitActorEvent(); + if (p_actor->GetUserNavFlag()) { + EmitGameEvent(e_hitActor); + } VTable0xc4(); SetActorState(c_two | c_noCollide); Mx3DPointFloat dir = p_actor->GetWorldDirection(); @@ -375,7 +379,7 @@ void LegoExtraActor::Animate(float p_time) MxS32 count = root->GetNumChildren(); 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); } } } diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index c9ce7c6c..2e9ae767 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -440,7 +440,7 @@ void LegoPathActor::Animate(float p_time) LegoWorld* world = CurrentWorld(); if (world) { - world->GetCameraController()->FUN_10012290(DTOR(m_unk0x14c)); + world->GetCameraController()->RotateZ(DTOR(m_unk0x14c)); } } } diff --git a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp index f4d09f9e..31600f3e 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp @@ -2,7 +2,7 @@ #include "decomp.h" #include "geom/legoorientededge.h" -#include "legolocomotionanimpresenter.h" +#include "legoanimpresenter.h" #include "legopathactor.h" #include "legopathstruct.h" diff --git a/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp b/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp index e269f727..276b66ab 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp @@ -3,7 +3,7 @@ #include "isle.h" #include "jukebox.h" #include "jukebox_actions.h" -#include "legohideanimpresenter.h" +#include "legoanimpresenter.h" #include "legopathactor.h" #include "legoutils.h" #include "misc.h" diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index 33ac928e..33c740a1 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -5,8 +5,8 @@ #include "isle.h" #include "jukebox_actions.h" #include "legoanimationmanager.h" +#include "legoanimpresenter.h" #include "legocontrolmanager.h" -#include "legohideanimpresenter.h" #include "legomain.h" #include "legonavcontroller.h" #include "legopathstruct.h" @@ -267,6 +267,8 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param) FALSE, TRUE ); + + EmitGameEvent(e_raceFinished); } result = 1; @@ -337,7 +339,7 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param) // FUNCTION: LEGO1 0x10017650 MxLong CarRace::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case 3: InvokeAction(Extra::e_stop, *g_carraceScript, CarraceScript::c_irtx08ra_PlayWav, NULL); diff --git a/LEGO1/lego/legoomni/src/race/jetskirace.cpp b/LEGO1/lego/legoomni/src/race/jetskirace.cpp index 2eaa986d..f906c0d9 100644 --- a/LEGO1/lego/legoomni/src/race/jetskirace.cpp +++ b/LEGO1/lego/legoomni/src/race/jetskirace.cpp @@ -6,8 +6,8 @@ #include "jetski_actions.h" #include "jukebox_actions.h" #include "legoanimationmanager.h" +#include "legoanimpresenter.h" #include "legocontrolmanager.h" -#include "legohideanimpresenter.h" #include "legomain.h" #include "legopathstruct.h" #include "legoracers.h" @@ -126,7 +126,7 @@ MxLong JetskiRace::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case JetraceScript::c_JetskiArms_Ctl: m_act1State->m_state = Act1State::e_none; @@ -206,6 +206,7 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param) m_destLocation = LegoGameState::e_jetrace2; TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); + EmitGameEvent(e_raceFinished); } result = 1; diff --git a/LEGO1/lego/legoomni/src/race/legoracemap.cpp b/LEGO1/lego/legoomni/src/race/legoracemap.cpp index bd0a04bd..9637114d 100644 --- a/LEGO1/lego/legoomni/src/race/legoracemap.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracemap.cpp @@ -129,7 +129,7 @@ MxLong LegoRaceMap::Notify(MxParam& p_param) if (param.GetNotification() == c_notificationControl && 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; FUN_1005d4b0(); m_stillPresenter->Enable(TRUE); diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index 74fd9f9a..d6b25088 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -340,10 +340,10 @@ void LegoRaceCar::KickCamera(float p_param) transformationMatrix.SetIdentity(); // 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()) { - r->GetCameraController()->FUN_100123e0(transformationMatrix, 0); + r->GetCameraController()->TransformPointOfView(transformationMatrix, 0); } m_roi->SetLocal2World(transformationMatrix); @@ -392,6 +392,7 @@ MxU32 LegoRaceCar::HandleSkeletonKicks(float p_param1) m_kickStart = p_param1; SoundManager()->GetCacheSoundManager()->Play(g_soundSkel3, NULL, FALSE); + EmitGameEvent(e_skeletonKick); return TRUE; } @@ -528,6 +529,9 @@ MxResult LegoRaceCar::HitActor(LegoPathActor* p_actor, MxBool p_bool) } } } + else { + EmitGameEvent(e_hitActor); + } return SUCCESS; } @@ -726,6 +730,9 @@ MxResult LegoJetski::HitActor(LegoPathActor* p_actor, MxBool p_bool) } } } + else { + EmitGameEvent(e_hitActor); + } return SUCCESS; } diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index a5a30466..9e31e18b 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -3,6 +3,7 @@ #include "3dmanager/lego3dmanager.h" #include "anim/legoanim.h" #include "define.h" +#include "legoanimactor.h" #include "legoanimationmanager.h" #include "legoanimmmpresenter.h" #include "legocameracontroller.h" @@ -30,6 +31,10 @@ #include 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: 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 @@ -936,14 +941,14 @@ void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p if (p_anim->GetCamAnim() != NULL) { 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) { - 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 @@ -1219,3 +1224,439 @@ MxResult LegoAnimPresenter::VTable0x98(LegoPathBoundary* p_boundary) 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((*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); + } + } +} diff --git a/LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp b/LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp index 9aeabf74..cc6d62f4 100644 --- a/LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp @@ -4,6 +4,8 @@ #include "misc/legocontainer.h" #include "mxdsaction.h" +#include + DECOMP_SIZE_ASSERT(LegoFlcTexturePresenter, 0x70) // FUNCTION: LEGO1 0x1005de80 @@ -27,11 +29,14 @@ void LegoFlcTexturePresenter::StartingTickle() char* pp; char extraCopy[128]; m_action->GetExtra(extraLength, pp); + assert(pp); if (pp != NULL) { strcpy(extraCopy, pp); strcat(extraCopy, ".gif"); - m_texture = TextureContainer()->Get(extraCopy); + LegoTextureContainer* textureContainer = TextureContainer(); + assert(textureContainer); + m_texture = textureContainer->Get(extraCopy); } MxFlcPresenter::StartingTickle(); diff --git a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp deleted file mode 100644 index 60f8dce5..00000000 --- a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include "legohideanimpresenter.h" - -#include "anim/legoanim.h" -#include "legomain.h" -#include "legoworld.h" -#include "misc.h" - -DECOMP_SIZE_ASSERT(LegoHideAnimPresenter, 0xc4) -DECOMP_SIZE_ASSERT(LegoHideAnimStruct, 0x08) - -// 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) -{ - m_criticalSection.Enter(); - - 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((*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); - } - } -} diff --git a/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp deleted file mode 100644 index 90b98e91..00000000 --- a/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "legolocomotionanimpresenter.h" - -#include "anim/legoanim.h" -#include "legoanimactor.h" -#include "legomain.h" -#include "legoworld.h" -#include "misc.h" -#include "mxautolock.h" -#include "mxdssubscriber.h" -#include "mxmisc.h" -#include "mxvariabletable.h" - -DECOMP_SIZE_ASSERT(LegoLocomotionAnimPresenter, 0xd8) - -// 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) -{ - m_criticalSection.Enter(); - - 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) -{ - 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; - } -} diff --git a/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp deleted file mode 100644 index cf75ce47..00000000 --- a/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "legoloopinganimpresenter.h" - -#include "anim/legoanim.h" -#include "legocameracontroller.h" -#include "legoworld.h" -#include "mxcompositepresenter.h" -#include "mxdsaction.h" -#include "mxdssubscriber.h" - -DECOMP_SIZE_ASSERT(LegoLoopingAnimPresenter, 0xc0) - -// 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(); - } - } - } -} diff --git a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp index 510c5928..8f918c8b 100644 --- a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp @@ -35,7 +35,7 @@ void LegoModelPresenter::configureLegoModelPresenter(MxS32 p_modelPresenterConfi // FUNCTION: LEGO1 0x1007f670 void LegoModelPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); m_roi = NULL; m_addedToView = FALSE; m_criticalSection.Leave(); @@ -46,7 +46,7 @@ void LegoModelPresenter::Destroy(MxBool p_fromDestructor) } // FUNCTION: LEGO1 0x1007f6b0 -// FUNCTION: BETA10 0x1009845e +// STUB: BETA10 0x1009845e MxResult LegoModelPresenter::CreateROI(MxDSChunk* p_chunk) { MxResult result = FAILURE; diff --git a/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp b/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp index ea5c7326..e76b90d9 100644 --- a/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp @@ -31,7 +31,7 @@ void LegoPalettePresenter::Init() // FUNCTION: LEGO1 0x1007a0e0 void LegoPalettePresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_palette) { delete m_palette; } diff --git a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp index 4849e747..10b72caa 100644 --- a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp @@ -22,6 +22,8 @@ MxS32 g_partPresenterConfig1 = 1; // GLOBAL: LEGO1 0x100f7aa4 MxS32 g_partPresenterConfig2 = 100; +vector LegoPartPresenter::g_lodLists; + // FUNCTION: LEGO1 0x1007c990 void LegoPartPresenter::configureLegoPartPresenter(MxS32 p_partPresenterConfig1, MxS32 p_partPresenterConfig2) { @@ -39,7 +41,7 @@ MxResult LegoPartPresenter::AddToManager() // FUNCTION: LEGO1 0x1007c9d0 void LegoPartPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); VideoManager()->UnregisterPresenter(*this); if (m_parts) { @@ -261,6 +263,8 @@ void LegoPartPresenter::Store() lodCursor.Detach(); lodList->PushBack(lod); } + + g_lodLists.push_back(lodList); } else { lodList->Release(); diff --git a/LEGO1/lego/legoomni/src/video/legophonemepresenter.cpp b/LEGO1/lego/legoomni/src/video/legophonemepresenter.cpp index 353480fc..6ea4d36d 100644 --- a/LEGO1/lego/legoomni/src/video/legophonemepresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legophonemepresenter.cpp @@ -25,8 +25,8 @@ void LegoPhonemePresenter::Init() { m_rectCount = 0; m_textureInfo = NULL; - m_unk0x70 = FALSE; - m_unk0x84 = FALSE; + m_reusedPhoneme = FALSE; + m_isPartOfAnimMM = FALSE; } // FUNCTION: LEGO1 0x1004e3d0 @@ -49,7 +49,7 @@ void LegoPhonemePresenter::StartingTickle() if (m_compositePresenter != NULL && m_compositePresenter->IsA("LegoAnimMMPresenter")) { entityROI = FindROI(m_roiName.GetData()); - m_unk0x84 = TRUE; + m_isPartOfAnimMM = TRUE; } else { entityROI = CharacterManager()->GetActorROI(m_roiName.GetData(), TRUE); @@ -81,7 +81,7 @@ void LegoPhonemePresenter::StartingTickle() phoneme->SetCount(phoneme->GetCount() + 1); cursor.SetValue(phoneme); - m_unk0x70 = TRUE; + m_reusedPhoneme = TRUE; } } } @@ -139,7 +139,7 @@ void LegoPhonemePresenter::EndAction() if (phoneme->GetCount() == 1) { LegoROI* roi; - if (m_unk0x84) { + if (m_isPartOfAnimMM) { roi = FindROI(m_roiName.GetData()); } else { @@ -150,7 +150,7 @@ void LegoPhonemePresenter::EndAction() CharacterManager()->SetHeadTexture(roi, NULL); } - if (!m_unk0x84) { + if (!m_isPartOfAnimMM) { CharacterManager()->ReleaseActor(m_roiName.GetData()); } @@ -163,7 +163,7 @@ void LegoPhonemePresenter::EndAction() cursor.SetValue(phoneme); } - if (!m_unk0x84) { + if (!m_isPartOfAnimMM) { CharacterManager()->ReleaseActor(m_roiName.GetData()); } } diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index 383c6d35..fe56a353 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -28,6 +28,7 @@ DECOMP_SIZE_ASSERT(MxStopWatch, 0x18) DECOMP_SIZE_ASSERT(MxFrequencyMeter, 0x20) // FUNCTION: LEGO1 0x1007aa20 +// FUNCTION: BETA10 0x100d5a00 LegoVideoManager::LegoVideoManager() { m_renderer = NULL; @@ -296,12 +297,15 @@ void LegoVideoManager::ToggleFPS(MxBool p_visible) } // FUNCTION: LEGO1 0x1007b770 +// STUB: BETA10 0x100d69cc MxResult LegoVideoManager::Tickle() { +#ifndef BETA10 if (m_unk0x554 && !m_videoParam.Flags().GetFlipSurfaces() && TransitionManager()->GetTransitionType() == MxTransitionManager::e_idle) { Sleep(30); } +#endif m_stopWatch->Stop(); m_elapsedSeconds = m_stopWatch->ElapsedSeconds(); @@ -467,6 +471,7 @@ void LegoVideoManager::DrawFPS() } // FUNCTION: LEGO1 0x1007c080 +// FUNCTION: BETA10 0x100d6d28 MxPresenter* LegoVideoManager::GetPresenterAt(MxS32 p_x, MxS32 p_y) { MxPresenterListCursor cursor(m_presenters); @@ -504,6 +509,7 @@ MxPresenter* LegoVideoManager::GetPresenterByActionObjectName(const char* p_acti } // FUNCTION: LEGO1 0x1007c290 +// FUNCTION: BETA10 0x100d731e MxResult LegoVideoManager::RealizePalette(MxPalette* p_pallete) { if (p_pallete && m_videoParam.GetPalette()) { @@ -545,14 +551,14 @@ void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable, MxBool p_scale) m_palette = m_videoParam.GetPalette()->Clone(); OverrideSkyColor(FALSE); - m_displaySurface->GetVideoParam().Flags().SetF1bit3(p_scale); + m_displaySurface->GetVideoParam().Flags().SetDoubleScaling(p_scale); m_render3d = FALSE; m_fullScreenMovie = TRUE; } else { m_displaySurface->ClearScreen(); - m_displaySurface->GetVideoParam().Flags().SetF1bit3(FALSE); + m_displaySurface->GetVideoParam().Flags().SetDoubleScaling(FALSE); // restore previous pallete RealizePalette(m_palette); @@ -577,10 +583,10 @@ void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable, MxBool p_scale) } if (p_enable) { - m_displaySurface->GetVideoParam().Flags().SetF1bit3(p_scale); + m_displaySurface->GetVideoParam().Flags().SetDoubleScaling(p_scale); } else { - m_displaySurface->GetVideoParam().Flags().SetF1bit3(FALSE); + m_displaySurface->GetVideoParam().Flags().SetDoubleScaling(FALSE); } } @@ -605,6 +611,7 @@ void LegoVideoManager::OverrideSkyColor(MxBool p_shouldOverride) } // FUNCTION: LEGO1 0x1007c4d0 +// FUNCTION: BETA10 0x100d77d3 void LegoVideoManager::UpdateView(MxU32 p_x, MxU32 p_y, MxU32 p_width, MxU32 p_height) { if (p_width == 0) { diff --git a/LEGO1/lego/legoomni/src/worlds/act3.cpp b/LEGO1/lego/legoomni/src/worlds/act3.cpp index af9cd09b..4a473611 100644 --- a/LEGO1/lego/legoomni/src/worlds/act3.cpp +++ b/LEGO1/lego/legoomni/src/worlds/act3.cpp @@ -782,6 +782,7 @@ void Act3::GoodEnding(const Matrix4& p_destination) m_cop2->SetActorState(LegoPathActor::c_disabled); m_brickster->SetActorState(LegoPathActor::c_disabled); +#ifndef BETA10 m_unk0x4220.Clear(); m_copter->FUN_10004640(p_destination); @@ -793,6 +794,12 @@ void Act3::GoodEnding(const Matrix4& p_destination) m_copter->m_unk0x1a8, m_copter->m_unk0x1f4 ); + + EmitGameEvent(e_goodEnding); +#else + m_state->m_unk0x08 = 2; + GameState()->SwitchArea(LegoGameState::Area::e_infomain); +#endif } // FUNCTION: LEGO1 0x10073500 @@ -872,6 +879,8 @@ void Act3::BadEnding(const Matrix4& p_destination) m_copter->m_unk0x1a8, m_copter->m_unk0x1f4 ); + + EmitGameEvent(e_badEnding); } // FUNCTION: LEGO1 0x10073a60 diff --git a/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp b/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp index 2a9c0772..6e1d484d 100644 --- a/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp +++ b/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp @@ -87,7 +87,7 @@ MxLong ElevatorBottom::HandleControl(LegoControlManagerNotificationParam& p_para { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case ElevbottScript::c_LeftArrow_Ctl: m_destLocation = LegoGameState::e_infodoor; diff --git a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp index 61a13858..d83c172d 100644 --- a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp +++ b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp @@ -389,7 +389,7 @@ MxLong GasStation::HandleButtonDown(LegoControlManagerNotificationParam& p_param // FUNCTION: BETA10 0x10029445 MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { MxDSAction action; switch (p_param.m_clickedObjectId) { diff --git a/LEGO1/lego/legoomni/src/worlds/hospital.cpp b/LEGO1/lego/legoomni/src/worlds/hospital.cpp index 229e11f8..cd75e1a1 100644 --- a/LEGO1/lego/legoomni/src/worlds/hospital.cpp +++ b/LEGO1/lego/legoomni/src/worlds/hospital.cpp @@ -555,7 +555,7 @@ MxLong Hospital::HandleButtonDown(LegoControlManagerNotificationParam& p_param) // FUNCTION: LEGO1 0x10075f90 MxBool Hospital::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case HospitalScript::c_Info_Ctl: BackgroundAudioManager()->RaiseVolume(); diff --git a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp index bf5a29b4..3e4eb728 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp @@ -190,12 +190,13 @@ MxResult Infocenter::Create(MxDSAction& p_dsAction) m_infocenterState = (InfocenterState*) GameState()->GetState("InfocenterState"); if (!m_infocenterState) { m_infocenterState = (InfocenterState*) GameState()->CreateState("InfocenterState"); - m_infocenterState->m_unk0x74 = 3; + m_infocenterState->m_state = InfocenterState::e_newState; } else { - if (m_infocenterState->m_unk0x74 != 8 && m_infocenterState->m_unk0x74 != 4 && - m_infocenterState->m_unk0x74 != 15) { - m_infocenterState->m_unk0x74 = 2; + if (m_infocenterState->m_state != InfocenterState::e_exitQueried && + m_infocenterState->m_state != InfocenterState::e_selectedSave && + m_infocenterState->m_state != InfocenterState::e_backToInfoAct1) { + m_infocenterState->m_state = InfocenterState::e_notRegistered; } MxS16 count, i; @@ -217,7 +218,7 @@ MxResult Infocenter::Create(MxDSAction& p_dsAction) GameState()->m_currentArea = LegoGameState::e_infomain; GameState()->StopArea(LegoGameState::e_previousArea); - if (m_infocenterState->m_unk0x74 == 4) { + if (m_infocenterState->m_state == InfocenterState::e_selectedSave) { LegoGameState* state = GameState(); state->m_previousArea = GameState()->m_unk0x42c; } @@ -266,9 +267,9 @@ MxLong Infocenter::Notify(MxParam& p_param) StopBookAnimation(); m_bookAnimationTimer = 0; - if (m_infocenterState->m_unk0x74 == 0x0c) { + if (m_infocenterState->m_state == InfocenterState::e_exiting) { StartCredits(); - m_infocenterState->m_unk0x74 = 0xd; + m_infocenterState->m_state = InfocenterState::e_playCredits; } else if (m_destLocation != 0) { BackgroundAudioManager()->RaiseVolume(); @@ -346,8 +347,8 @@ MxLong Infocenter::HandleEndAction(MxEndActionNotificationParam& p_param) m_bigInfoBlinkTimer = 0; } - switch (m_infocenterState->m_unk0x74) { - case 0: + switch (m_infocenterState->m_state) { + case InfocenterState::e_playCutscene: switch (m_currentCutscene) { case e_legoMovie: PlayCutscene(e_mindscapeMovie, FALSE); @@ -357,13 +358,13 @@ MxLong Infocenter::HandleEndAction(MxEndActionNotificationParam& p_param) return 1; case e_badEndMovie: StopCutscene(); - m_infocenterState->m_unk0x74 = 11; + m_infocenterState->m_state = InfocenterState::e_welcomeAnimation; PlayAction(InfomainScript::c_tic092in_RunAnim); m_currentCutscene = e_noIntro; return 1; case e_goodEndMovie: StopCutscene(); - m_infocenterState->m_unk0x74 = 11; + m_infocenterState->m_state = InfocenterState::e_welcomeAnimation; PlayAction(InfomainScript::c_tic089in_RunAnim); m_currentCutscene = e_noIntro; return 1; @@ -371,7 +372,7 @@ MxLong Infocenter::HandleEndAction(MxEndActionNotificationParam& p_param) // default / 2nd case probably? StopCutscene(); - m_infocenterState->m_unk0x74 = 11; + m_infocenterState->m_state = InfocenterState::e_welcomeAnimation; PlayAction(InfomainScript::c_iic001in_RunAnim); m_currentCutscene = e_noIntro; @@ -380,8 +381,8 @@ MxLong Infocenter::HandleEndAction(MxEndActionNotificationParam& p_param) return 1; } break; - case 1: - m_infocenterState->m_unk0x74 = 11; + case InfocenterState::e_introCancelled: + m_infocenterState->m_state = InfocenterState::e_welcomeAnimation; switch (m_currentCutscene) { case e_badEndMovie: @@ -396,30 +397,30 @@ MxLong Infocenter::HandleEndAction(MxEndActionNotificationParam& p_param) m_currentCutscene = e_noIntro; return 1; - case 2: + case InfocenterState::e_notRegistered: SetROIVisible(g_object2x4red, FALSE); SetROIVisible(g_object2x4grn, FALSE); BackgroundAudioManager()->RaiseVolume(); return 1; - case 4: + case InfocenterState::e_selectedSave: if (action->GetObjectId() == InfomainScript::c_GoTo_RegBook || action->GetObjectId() == InfomainScript::c_GoTo_RegBook_Red) { TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); - m_infocenterState->m_unk0x74 = 14; + m_infocenterState->m_state = InfocenterState::e_exitingToIsland; return 1; } break; - case 5: + case InfocenterState::e_selectedCharacterAndDestination: if (action->GetObjectId() == m_currentInfomainScript) { if (GameState()->GetCurrentAct() != LegoGameState::e_act3 && m_selectedCharacter != e_noCharacter) { GameState()->SetActor(m_selectedCharacter); } TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); - m_infocenterState->m_unk0x74 = 14; + m_infocenterState->m_state = InfocenterState::e_exitingToIsland; return 1; } break; - case 11: + case InfocenterState::e_welcomeAnimation: if (!m_infocenterState->HasRegistered() && m_currentInfomainScript != InfomainScript::c_Mama_All_Movie && m_currentInfomainScript != InfomainScript::c_Papa_All_Movie && m_currentInfomainScript != InfomainScript::c_Pepper_All_Movie && @@ -429,10 +430,10 @@ MxLong Infocenter::HandleEndAction(MxEndActionNotificationParam& p_param) PlayMusic(JukeboxScript::c_InformationCenter_Music); } - m_infocenterState->m_unk0x74 = 2; + m_infocenterState->m_state = InfocenterState::e_notRegistered; SetROIVisible("infoman", TRUE); return 1; - case 12: + case InfocenterState::e_exiting: if (action->GetObjectId() == m_currentInfomainScript) { TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); } @@ -459,13 +460,13 @@ void Infocenter::ReadyWorld() bg->Enable(TRUE); InitializeBitmaps(); - switch (m_infocenterState->m_unk0x74) { - case 3: + switch (m_infocenterState->m_state) { + case InfocenterState::e_newState: PlayCutscene(e_legoMovie, TRUE); - m_infocenterState->m_unk0x74 = 0; + m_infocenterState->m_state = InfocenterState::e_playCutscene; return; - case 4: - m_infocenterState->m_unk0x74 = 2; + case InfocenterState::e_selectedSave: + m_infocenterState->m_state = InfocenterState::e_notRegistered; if (!m_infocenterState->HasRegistered()) { m_bookAnimationTimer = 1; } @@ -474,7 +475,7 @@ void Infocenter::ReadyWorld() PlayMusic(JukeboxScript::c_InformationCenter_Music); Disable(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); return; - case 5: + case InfocenterState::e_selectedCharacterAndDestination: default: { PlayMusic(JukeboxScript::c_InformationCenter_Music); @@ -493,13 +494,13 @@ void Infocenter::ReadyWorld() break; } - case 8: + case InfocenterState::e_exitQueried: PlayMusic(JukeboxScript::c_InformationCenter_Music); PlayAction(InfomainScript::c_iic043in_RunAnim); Disable(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); return; - case 0xf: - m_infocenterState->m_unk0x74 = 2; + case InfocenterState::e_backToInfoAct1: + m_infocenterState->m_state = InfocenterState::e_notRegistered; if (!m_infocenterState->HasRegistered()) { m_bookAnimationTimer = 1; } @@ -511,7 +512,7 @@ void Infocenter::ReadyWorld() } break; case LegoGameState::e_act2: { - if (m_infocenterState->m_unk0x74 == 8) { + if (m_infocenterState->m_state == InfocenterState::e_exitQueried) { PlayMusic(JukeboxScript::c_InformationCenter_Music); bgRed->Enable(TRUE); PlayAction(InfomainScript::c_iic043in_RunAnim); @@ -525,11 +526,11 @@ void Infocenter::ReadyWorld() if (state && state->GetUnknown0x08() == 0x68) { bg->Enable(TRUE); PlayCutscene(e_badEndMovie, TRUE); - m_infocenterState->m_unk0x74 = 0; + m_infocenterState->m_state = InfocenterState::e_playCutscene; return; } - if (m_infocenterState->m_unk0x74 == 4) { + if (m_infocenterState->m_state == InfocenterState::e_selectedSave) { bgRed->Enable(TRUE); if (GameState()->GetCurrentAct() == GameState()->GetLoadedAct()) { @@ -538,7 +539,7 @@ void Infocenter::ReadyWorld() GameState()->m_currentArea = LegoGameState::e_infomain; } - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; m_destLocation = LegoGameState::e_act2main; InfomainScript::Script script = m_infocenterState->GetNextReturnDialogue(); @@ -556,7 +557,7 @@ void Infocenter::ReadyWorld() break; } case LegoGameState::e_act3: { - if (m_infocenterState->m_unk0x74 == 8) { + if (m_infocenterState->m_state == InfocenterState::e_exitQueried) { PlayMusic(JukeboxScript::c_InformationCenter_Music); bgRed->Enable(TRUE); PlayAction(InfomainScript::c_iic043in_RunAnim); @@ -570,18 +571,18 @@ void Infocenter::ReadyWorld() if (state && state->GetUnknown0x08() == 3) { bg->Enable(TRUE); PlayCutscene(e_badEndMovie, TRUE); - m_infocenterState->m_unk0x74 = 0; + m_infocenterState->m_state = InfocenterState::e_playCutscene; return; } if (state && state->GetUnknown0x08() == 2) { bg->Enable(TRUE); PlayCutscene(e_goodEndMovie, TRUE); - m_infocenterState->m_unk0x74 = 0; + m_infocenterState->m_state = InfocenterState::e_playCutscene; return; } - if (m_infocenterState->m_unk0x74 == 4) { + if (m_infocenterState->m_state == InfocenterState::e_selectedSave) { bgRed->Enable(TRUE); if (GameState()->GetCurrentAct() == GameState()->GetLoadedAct()) { @@ -590,7 +591,7 @@ void Infocenter::ReadyWorld() GameState()->m_currentArea = LegoGameState::e_infomain; } - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; m_destLocation = LegoGameState::e_act3script; InfomainScript::Script script = m_infocenterState->GetNextReturnDialogue(); @@ -609,7 +610,7 @@ void Infocenter::ReadyWorld() } } - m_infocenterState->m_unk0x74 = 11; + m_infocenterState->m_state = InfocenterState::e_welcomeAnimation; Disable(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); } @@ -708,37 +709,37 @@ MxLong Infocenter::HandleKeyPress(SDL_Keycode p_key) MxLong result = 0; if (p_key == SDLK_SPACE && m_worldStarted) { - switch (m_infocenterState->m_unk0x74) { - case 0: + switch (m_infocenterState->m_state) { + case InfocenterState::e_playCutscene: StopCutscene(); - m_infocenterState->m_unk0x74 = 1; + m_infocenterState->m_state = InfocenterState::e_introCancelled; if (!m_infocenterState->HasRegistered()) { m_bookAnimationTimer = 1; return 1; } break; - case 1: - case 4: + case InfocenterState::e_introCancelled: + case InfocenterState::e_selectedSave: break; default: { InfomainScript::Script script = m_currentInfomainScript; StopCurrentAction(); - switch (m_infocenterState->m_unk0x74) { - case 5: - case 12: + switch (m_infocenterState->m_state) { + case InfocenterState::e_selectedCharacterAndDestination: + case InfocenterState::e_exiting: m_currentInfomainScript = script; return 1; default: - m_infocenterState->m_unk0x74 = 2; + m_infocenterState->m_state = InfocenterState::e_notRegistered; return 1; - case 8: - case 11: + case InfocenterState::e_exitQueried: + case InfocenterState::e_welcomeAnimation: break; } } - case 13: + case InfocenterState::e_playCredits: StopCredits(); break; } @@ -849,37 +850,37 @@ MxU8 Infocenter::HandleButtonUp(MxS32 p_x, MxS32 p_y) case InfocenterMapEntry::e_jetrace: if (m_selectedCharacter) { m_destLocation = LegoGameState::e_jetraceExterior; - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; } break; case InfocenterMapEntry::e_carrace: if (m_selectedCharacter) { m_destLocation = LegoGameState::e_carraceExterior; - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; } break; case InfocenterMapEntry::e_pizzeria: if (m_selectedCharacter) { m_destLocation = LegoGameState::e_pizzeriaExterior; - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; } break; case InfocenterMapEntry::e_garage: if (m_selectedCharacter) { m_destLocation = LegoGameState::e_garageExterior; - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; } break; case InfocenterMapEntry::e_hospital: if (m_selectedCharacter) { m_destLocation = LegoGameState::e_hospitalExterior; - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; } break; case InfocenterMapEntry::e_police: if (m_selectedCharacter) { m_destLocation = LegoGameState::e_policeExterior; - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; } break; } @@ -889,13 +890,13 @@ MxU8 Infocenter::HandleButtonUp(MxS32 p_x, MxS32 p_y) m_dragPresenter->Enable(FALSE); m_dragPresenter = NULL; - if (m_infocenterState->m_unk0x74 == 5) { + if (m_infocenterState->m_state == InfocenterState::e_selectedCharacterAndDestination) { InfomainScript::Script dialogueToPlay; if (GameState()->GetCurrentAct() == LegoGameState::e_act1) { if (!m_infocenterState->HasRegistered()) { dialogueToPlay = InfomainScript::c_iic007in_PlayWav; - m_infocenterState->m_unk0x74 = 2; + m_infocenterState->m_state = InfocenterState::e_notRegistered; m_destLocation = LegoGameState::e_undefined; } else { @@ -948,7 +949,7 @@ MxU8 Infocenter::HandleButtonUp(MxS32 p_x, MxS32 p_y) // FUNCTION: BETA10 0x1002ffd4 MxU8 Infocenter::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { m_infoManDialogueTimer = 0; InfomainScript::Script actionToPlay = InfomainScript::c_noneInfomain; @@ -959,7 +960,7 @@ MxU8 Infocenter::HandleControl(LegoControlManagerNotificationParam& p_param) switch (p_param.m_clickedObjectId) { case InfomainScript::c_LeftArrow_Ctl: - m_infocenterState->m_unk0x74 = 14; + m_infocenterState->m_state = InfocenterState::e_exitingToIsland; StopCurrentAction(); if (GameState()->GetCurrentAct() == LegoGameState::e_act1) { @@ -974,7 +975,7 @@ MxU8 Infocenter::HandleControl(LegoControlManagerNotificationParam& p_param) break; case InfomainScript::c_RightArrow_Ctl: - m_infocenterState->m_unk0x74 = 14; + m_infocenterState->m_state = InfocenterState::e_exitingToIsland; StopCurrentAction(); if (GameState()->GetCurrentAct() == LegoGameState::e_act1) { @@ -993,10 +994,10 @@ MxU8 Infocenter::HandleControl(LegoControlManagerNotificationParam& p_param) m_radio.Stop(); break; case InfomainScript::c_Door_Ctl: - if (m_infocenterState->m_unk0x74 != 8) { + if (m_infocenterState->m_state != InfocenterState::e_exitQueried) { actionToPlay = InfomainScript::c_iic043in_RunAnim; m_radio.Stop(); - m_infocenterState->m_unk0x74 = 8; + m_infocenterState->m_state = InfocenterState::e_exitQueried; } break; @@ -1032,7 +1033,7 @@ MxU8 Infocenter::HandleControl(LegoControlManagerNotificationParam& p_param) case LegoGameState::e_infodoor: case LegoGameState::e_regbook: case LegoGameState::e_infoscor: - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; m_destLocation = state->m_previousArea; actionToPlay = (InfomainScript::Script) m_infocenterState->GetNextLeaveDialogue(); m_radio.Stop(); @@ -1051,10 +1052,10 @@ MxU8 Infocenter::HandleControl(LegoControlManagerNotificationParam& p_param) if (state->GetActorId() != LegoActor::c_none) { if (!m_infocenterState->HasRegistered()) { PlayAction(InfomainScript::c_iic007in_PlayWav); - m_infocenterState->m_unk0x74 = 2; + m_infocenterState->m_state = InfocenterState::e_notRegistered; } else { - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; m_destLocation = state->m_previousArea; actionToPlay = (InfomainScript::Script) m_infocenterState->GetNextLeaveDialogue(); m_radio.Stop(); @@ -1067,14 +1068,14 @@ MxU8 Infocenter::HandleControl(LegoControlManagerNotificationParam& p_param) } break; case LegoGameState::e_act2: - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; m_destLocation = LegoGameState::e_act2main; actionToPlay = (InfomainScript::Script) m_infocenterState->GetNextLeaveDialogue(); InputManager()->DisableInputProcessing(); InputManager()->SetUnknown336(TRUE); break; case LegoGameState::e_act3: - m_infocenterState->m_unk0x74 = 5; + m_infocenterState->m_state = InfocenterState::e_selectedCharacterAndDestination; m_destLocation = LegoGameState::e_act3script; actionToPlay = (InfomainScript::Script) m_infocenterState->GetNextLeaveDialogue(); InputManager()->DisableInputProcessing(); @@ -1084,7 +1085,7 @@ MxU8 Infocenter::HandleControl(LegoControlManagerNotificationParam& p_param) break; case InfomainScript::c_Book_Ctl: m_destLocation = LegoGameState::e_regbook; - m_infocenterState->m_unk0x74 = 4; + m_infocenterState->m_state = InfocenterState::e_selectedSave; actionToPlay = GameState()->GetCurrentAct() != LegoGameState::e_act1 ? InfomainScript::c_GoTo_RegBook_Red : InfomainScript::c_GoTo_RegBook; m_radio.Stop(); @@ -1135,13 +1136,13 @@ MxLong Infocenter::HandleNotification0(MxNotificationParam& p_param) MxCore* sender = p_param.GetSender(); if (sender == NULL) { - if (m_infocenterState->m_unk0x74 == 8) { + if (m_infocenterState->m_state == InfocenterState::e_exitQueried) { m_infoManDialogueTimer = 0; StopCutscene(); PlayAction(InfomainScript::c_iic043in_RunAnim); } } - else if (sender->IsA("MxEntity") && m_infocenterState->m_unk0x74 != 5 && m_infocenterState->m_unk0x74 != 12) { + else if (sender->IsA("MxEntity") && m_infocenterState->m_state != InfocenterState::e_selectedCharacterAndDestination && m_infocenterState->m_state != InfocenterState::e_exiting) { switch (((MxEntity*) sender)->GetEntityId()) { case 5: { m_infoManDialogueTimer = 0; @@ -1160,21 +1161,21 @@ MxLong Infocenter::HandleNotification0(MxNotificationParam& p_param) return 1; } case 6: - if (m_infocenterState->m_unk0x74 == 8) { + if (m_infocenterState->m_state == InfocenterState::e_exitQueried) { StopCurrentAction(); SetROIVisible(g_object2x4red, FALSE); SetROIVisible(g_object2x4grn, FALSE); - m_infocenterState->m_unk0x74 = 2; + m_infocenterState->m_state = InfocenterState::e_notRegistered; PlayAction(InfomainScript::c_iicb28in_RunAnim); return 1; } case 7: - if (m_infocenterState->m_unk0x74 == 8) { + if (m_infocenterState->m_state == InfocenterState::e_exitQueried) { if (m_infocenterState->HasRegistered()) { GameState()->Save(0); } - m_infocenterState->m_unk0x74 = 12; + m_infocenterState->m_state = InfocenterState::e_exiting; PlayAction(InfomainScript::c_iic046in_RunAnim); InputManager()->DisableInputProcessing(); InputManager()->SetUnknown336(TRUE); @@ -1416,17 +1417,17 @@ void Infocenter::Reset() MxBool Infocenter::Escape() { if (m_infocenterState != NULL) { - MxU32 val = m_infocenterState->m_unk0x74; + MxU32 val = m_infocenterState->m_state; - if (val == 0) { + if (val == InfocenterState::e_playCutscene) { StopCutscene(); - m_infocenterState->m_unk0x74 = 1; + m_infocenterState->m_state = InfocenterState::e_introCancelled; } - else if (val == 13) { + else if (val == InfocenterState::e_playCredits) { StopCredits(); } - else if (val != 8) { - m_infocenterState->m_unk0x74 = 8; + else if (val != InfocenterState::e_exitQueried) { + m_infocenterState->m_state = InfocenterState::e_exitQueried; #ifdef COMPAT_MODE { diff --git a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp index 8f92a323..8dc21750 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp @@ -96,7 +96,7 @@ MxLong InfocenterDoor::HandleControl(LegoControlManagerNotificationParam& p_para { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { DeleteObjects(&m_atomId, InfodoorScript::c_iic037in_PlayWav, 510); switch (p_param.m_clickedObjectId) { diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 5e4f983f..322bb680 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -81,7 +81,7 @@ Isle::~Isle() } if (UserActor() != NULL) { - VTable0x6c(UserActor()); + RemoveVehicle(UserActor()); } NotificationManager()->Unregister(this); @@ -275,7 +275,7 @@ void Isle::ReadyWorld() } else if (GameState()->GetLoadedAct() != LegoGameState::e_act1) { EnableAnimations(TRUE); - FUN_10032620(); + CheckAreaExiting(); m_act1state->PlaceActors(); Disable(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); } @@ -284,7 +284,7 @@ void Isle::ReadyWorld() // FUNCTION: LEGO1 0x10031030 MxLong Isle::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { MxDSAction action; switch (p_param.m_clickedObjectId) { @@ -577,14 +577,14 @@ void Isle::Enable(MxBool p_enable) if (UserActor() != NULL && UserActor()->IsA("Jetski")) { IslePathActor* actor = (IslePathActor*) UserActor(); actor->SpawnPlayer( - LegoGameState::e_unk45, + LegoGameState::e_jetskiSpawn, FALSE, IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3 ); actor->SetActorState(LegoPathActor::c_initial); } else { - FUN_10032620(); + CheckAreaExiting(); } switch (GameState()->m_currentArea) { @@ -858,7 +858,7 @@ void Isle::Enable(MxBool p_enable) } // FUNCTION: LEGO1 0x10032620 -void Isle::FUN_10032620() +void Isle::CheckAreaExiting() { VideoManager()->Get3DManager()->SetFrustrum(90.0, 0.1, 250.0); @@ -909,17 +909,27 @@ MxLong Isle::HandleTransitionEnd() case LegoGameState::e_elevride: m_act1state->m_unk0x01f = TRUE; VariableTable()->SetVariable("VISIBILITY", "Hide infocen"); - FUN_10032d30(IsleScript::c_ElevRide_Background_Bitmap, JukeboxScript::c_Elevator_Music, "LCAMZI1,90", FALSE); + TransitionToOverlay( + IsleScript::c_ElevRide_Background_Bitmap, + JukeboxScript::c_Elevator_Music, + "LCAMZI1,90", + FALSE + ); break; case LegoGameState::e_elevride2: - FUN_10032d30(IsleScript::c_ElevRide_Background_Bitmap, JukeboxScript::c_Elevator_Music, "LCAMZI2,90", FALSE); + TransitionToOverlay( + IsleScript::c_ElevRide_Background_Bitmap, + JukeboxScript::c_Elevator_Music, + "LCAMZI2,90", + FALSE + ); if (m_destLocation == LegoGameState::e_undefined) { ((MxStillPresenter*) Find(m_atomId, IsleScript::c_Meter3_Bitmap))->Enable(TRUE); } break; case LegoGameState::e_elevopen: - FUN_10032d30( + TransitionToOverlay( IsleScript::c_ElevOpen_Background_Bitmap, JukeboxScript::c_InfoCenter_3rd_Floor_Music, "LCAMZIS,90", @@ -927,7 +937,7 @@ MxLong Isle::HandleTransitionEnd() ); break; case LegoGameState::e_seaview: - FUN_10032d30( + TransitionToOverlay( IsleScript::c_SeaView_Background_Bitmap, JukeboxScript::c_InfoCenter_3rd_Floor_Music, "LCAMZIE,90", @@ -935,7 +945,7 @@ MxLong Isle::HandleTransitionEnd() ); break; case LegoGameState::e_observe: - FUN_10032d30( + TransitionToOverlay( IsleScript::c_Observe_Background_Bitmap, JukeboxScript::c_InfoCenter_3rd_Floor_Music, "LCAMZIW,90", @@ -943,7 +953,7 @@ MxLong Isle::HandleTransitionEnd() ); break; case LegoGameState::e_elevdown: - FUN_10032d30( + TransitionToOverlay( IsleScript::c_ElevDown_Background_Bitmap, JukeboxScript::c_InfoCenter_3rd_Floor_Music, "LCAMZIN,90", @@ -953,7 +963,7 @@ MxLong Isle::HandleTransitionEnd() case LegoGameState::e_garadoor: m_act1state->m_unk0x01f = TRUE; VariableTable()->SetVariable("VISIBILITY", "Hide Gas"); - FUN_10032d30(IsleScript::c_GaraDoor_Background_Bitmap, JukeboxScript::c_JBMusic2, "LCAMZG1,90", FALSE); + TransitionToOverlay(IsleScript::c_GaraDoor_Background_Bitmap, JukeboxScript::c_JBMusic2, "LCAMZG1,90", FALSE); break; case LegoGameState::e_garageExited: GameState()->SwitchArea(m_destLocation); @@ -978,7 +988,7 @@ MxLong Isle::HandleTransitionEnd() case LegoGameState::e_polidoor: m_act1state->m_unk0x01f = TRUE; VariableTable()->SetVariable("VISIBILITY", "Hide Policsta"); - FUN_10032d30( + TransitionToOverlay( IsleScript::c_PoliDoor_Background_Bitmap, JukeboxScript::c_PoliceStation_Music, "LCAMZP1,90", @@ -987,7 +997,7 @@ MxLong Isle::HandleTransitionEnd() break; case LegoGameState::e_bike: m_act1state->m_unk0x01f = TRUE; - FUN_10032d30(IsleScript::c_BikeDashboard_Bitmap, JukeboxScript::c_MusicTheme1, NULL, TRUE); + TransitionToOverlay(IsleScript::c_BikeDashboard_Bitmap, JukeboxScript::c_MusicTheme1, NULL, TRUE); if (!m_act1state->m_unk0x01f) { m_bike->ActivateSceneActions(); @@ -995,7 +1005,7 @@ MxLong Isle::HandleTransitionEnd() break; case LegoGameState::e_dunecar: m_act1state->m_unk0x01f = TRUE; - FUN_10032d30(IsleScript::c_DuneCarFuelMeter, JukeboxScript::c_MusicTheme1, NULL, TRUE); + TransitionToOverlay(IsleScript::c_DuneCarFuelMeter, JukeboxScript::c_MusicTheme1, NULL, TRUE); if (!m_act1state->m_unk0x01f) { m_dunebuggy->ActivateSceneActions(); @@ -1003,7 +1013,7 @@ MxLong Isle::HandleTransitionEnd() break; case LegoGameState::e_motocycle: m_act1state->m_unk0x01f = TRUE; - FUN_10032d30(IsleScript::c_MotoBikeDashboard_Bitmap, JukeboxScript::c_MusicTheme1, NULL, TRUE); + TransitionToOverlay(IsleScript::c_MotoBikeDashboard_Bitmap, JukeboxScript::c_MusicTheme1, NULL, TRUE); if (!m_act1state->m_unk0x01f) { m_motocycle->ActivateSceneActions(); @@ -1011,11 +1021,11 @@ MxLong Isle::HandleTransitionEnd() break; case LegoGameState::e_copter: m_act1state->m_unk0x01f = TRUE; - FUN_10032d30(IsleScript::c_HelicopterDashboard_Bitmap, JukeboxScript::c_MusicTheme1, NULL, TRUE); + TransitionToOverlay(IsleScript::c_HelicopterDashboard_Bitmap, JukeboxScript::c_MusicTheme1, NULL, TRUE); break; case LegoGameState::e_skateboard: m_act1state->m_unk0x01f = TRUE; - FUN_10032d30(IsleScript::c_SkatePizza_Bitmap, JukeboxScript::c_MusicTheme1, NULL, TRUE); + TransitionToOverlay(IsleScript::c_SkatePizza_Bitmap, JukeboxScript::c_MusicTheme1, NULL, TRUE); if (!m_act1state->m_unk0x01f) { m_skateboard->ActivateSceneActions(); @@ -1024,7 +1034,7 @@ MxLong Isle::HandleTransitionEnd() case LegoGameState::e_ambulance: m_act1state->m_unk0x01f = TRUE; m_act1state->m_state = Act1State::e_ambulance; - FUN_10032d30(IsleScript::c_AmbulanceFuelMeter, JukeboxScript::c_MusicTheme1, NULL, TRUE); + TransitionToOverlay(IsleScript::c_AmbulanceFuelMeter, JukeboxScript::c_MusicTheme1, NULL, TRUE); if (!m_act1state->m_unk0x01f) { m_ambulance->ActivateSceneActions(); @@ -1033,7 +1043,7 @@ MxLong Isle::HandleTransitionEnd() case LegoGameState::e_towtrack: m_act1state->m_unk0x01f = TRUE; m_act1state->m_state = Act1State::e_towtrack; - FUN_10032d30(IsleScript::c_TowFuelMeter, JukeboxScript::c_MusicTheme1, NULL, TRUE); + TransitionToOverlay(IsleScript::c_TowFuelMeter, JukeboxScript::c_MusicTheme1, NULL, TRUE); if (!m_act1state->m_unk0x01f) { m_towtrack->ActivateSceneActions(); @@ -1041,7 +1051,12 @@ MxLong Isle::HandleTransitionEnd() break; case LegoGameState::e_jetski: m_act1state->m_unk0x01f = TRUE; - FUN_10032d30((IsleScript::Script) m_jetski->GetUnknown0x160(), JukeboxScript::c_MusicTheme1, NULL, TRUE); + TransitionToOverlay( + (IsleScript::Script) m_jetski->GetJetskiDashboardStreamId(), + JukeboxScript::c_MusicTheme1, + NULL, + TRUE + ); if (!m_act1state->m_unk0x01f) { m_jetski->ActivateSceneActions(); @@ -1056,11 +1071,11 @@ MxLong Isle::HandleTransitionEnd() } // FUNCTION: LEGO1 0x10032d30 -void Isle::FUN_10032d30( +void Isle::TransitionToOverlay( IsleScript::Script p_script, JukeboxScript::Script p_music, const char* p_cameraLocation, - MxBool p_und + MxBool p_setCamera ) { if (m_act1state->m_unk0x01f) { @@ -1071,7 +1086,7 @@ void Isle::FUN_10032d30( PlayMusic(p_music); } - if (p_und) { + if (p_setCamera) { InputManager()->SetCamera(m_cameraController); } else { @@ -1143,7 +1158,7 @@ void Isle::Add(MxCore* p_object) } // FUNCTION: LEGO1 0x10033050 -void Isle::VTable0x6c(LegoPathActor* p_actor) +void Isle::RemoveVehicle(LegoPathActor* p_actor) { LegoWorld::Remove(p_actor); @@ -1197,7 +1212,7 @@ MxBool Isle::Escape() case Act1State::e_pizza: if (UserActor() != NULL) { m_pizza->StopActions(); - m_pizza->FUN_100382b0(); + m_pizza->Reset(); } break; case Act1State::e_towtrack: @@ -1245,7 +1260,7 @@ MxBool Isle::Escape() } // FUNCTION: LEGO1 0x10033350 -void Isle::FUN_10033350() +void Isle::SwitchToInfocenter() { if (m_act1state->m_state == Act1State::e_ambulance) { if (UserActor() != NULL && !UserActor()->IsA("Ambulance")) { @@ -1264,7 +1279,7 @@ void Isle::FUN_10033350() if (m_act1state->m_state == Act1State::e_pizza) { if (UserActor() != NULL) { m_pizza->StopActions(); - m_pizza->FUN_100382b0(); + m_pizza->Reset(); } } @@ -1572,7 +1587,7 @@ void Act1State::RemoveActors() isle->m_helicopter->UpdatePlane(m_helicopterPlane); m_helicopter = isle->m_helicopter; isle->RemoveActor(m_helicopter); - isle->VTable0x6c(m_helicopter); + isle->RemoveVehicle(m_helicopter); m_helicopter->SetBoundary(NULL); m_helicopter->SetController(NULL); } @@ -1581,7 +1596,7 @@ void Act1State::RemoveActors() isle->m_jetski->UpdatePlane(m_jetskiPlane); m_jetski = isle->m_jetski; isle->RemoveActor(m_jetski); - isle->VTable0x6c(m_jetski); + isle->RemoveVehicle(m_jetski); m_jetski->SetBoundary(NULL); m_jetski->SetController(NULL); } @@ -1590,7 +1605,7 @@ void Act1State::RemoveActors() isle->m_dunebuggy->UpdatePlane(m_dunebuggyPlane); m_dunebuggy = isle->m_dunebuggy; isle->RemoveActor(m_dunebuggy); - isle->VTable0x6c(m_dunebuggy); + isle->RemoveVehicle(m_dunebuggy); m_dunebuggy->SetBoundary(NULL); m_dunebuggy->SetController(NULL); } @@ -1599,7 +1614,7 @@ void Act1State::RemoveActors() isle->m_racecar->UpdatePlane(m_racecarPlane); m_racecar = isle->m_racecar; isle->RemoveActor(m_racecar); - isle->VTable0x6c(m_racecar); + isle->RemoveVehicle(m_racecar); m_racecar->SetBoundary(NULL); m_racecar->SetController(NULL); } @@ -1633,7 +1648,7 @@ void Act1State::PlaceActors() if (m_helicopter != NULL) { if (!m_helicopterPlane.IsPresent()) { - m_helicopter->SpawnPlayer(LegoGameState::e_unk40, FALSE, 0); + m_helicopter->SpawnPlayer(LegoGameState::e_helicopterSpawn, FALSE, 0); } else { isle->PlaceActor(m_helicopter, m_helicopterPlane.GetName(), 0, 0.5f, 1, 0.5f); @@ -1673,7 +1688,7 @@ void Act1State::PlaceActors() if (m_jetski != NULL) { if (!m_jetskiPlane.IsPresent()) { - m_jetski->SpawnPlayer(LegoGameState::e_unk45, FALSE, 0); + m_jetski->SpawnPlayer(LegoGameState::e_jetskiSpawn, FALSE, 0); } else { isle->PlaceActor(m_jetski, m_jetskiPlane.GetName(), 0, 0.5f, 1, 0.5f); @@ -1703,7 +1718,7 @@ void Act1State::PlaceActors() if (m_dunebuggy != NULL) { if (!m_dunebuggyPlane.IsPresent()) { - m_dunebuggy->SpawnPlayer(LegoGameState::e_unk43, FALSE, 0); + m_dunebuggy->SpawnPlayer(LegoGameState::e_dunebuggySpawn, FALSE, 0); } else { isle->PlaceActor(m_dunebuggy, m_dunebuggyPlane.GetName(), 0, 0.5f, 1, 0.5f); @@ -1731,7 +1746,7 @@ void Act1State::PlaceActors() if (m_racecar != NULL) { if (!m_racecarPlane.IsPresent()) { - m_racecar->SpawnPlayer(LegoGameState::e_unk44, FALSE, 0); + m_racecar->SpawnPlayer(LegoGameState::e_racecarSpawn, FALSE, 0); } else { isle->PlaceActor(m_racecar, m_racecarPlane.GetName(), 0, 0.5f, 1, 0.5f); diff --git a/LEGO1/lego/legoomni/src/worlds/jukebox.cpp b/LEGO1/lego/legoomni/src/worlds/jukebox.cpp index db244e00..aa8858cf 100644 --- a/LEGO1/lego/legoomni/src/worlds/jukebox.cpp +++ b/LEGO1/lego/legoomni/src/worlds/jukebox.cpp @@ -123,7 +123,7 @@ MxBool JukeBox::HandleControl(LegoControlManagerNotificationParam& p_param) { MxStillPresenter* presenter; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case JukeboxwScript::c_Dback_Ctl: switch (m_state->m_music) { diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 5fe73440..c04bbdbc 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -7,10 +7,10 @@ #include "islepathactor.h" #include "jukebox_actions.h" #include "legoanimationmanager.h" +#include "legoanimpresenter.h" #include "legocachesoundmanager.h" #include "legogamestate.h" #include "legoinputmanager.h" -#include "legolocomotionanimpresenter.h" #include "legomain.h" #include "legopathstruct.h" #include "legosoundmanager.h" @@ -939,6 +939,7 @@ MxResult LegoAct2::BadEnding() MxTrace("Bad End of Act2\n"); m_unk0x10c4 = 14; + EmitGameEvent(e_badEnding); return SUCCESS; } @@ -1116,7 +1117,7 @@ MxResult LegoAct2::FUN_10052560( action.SetDirection(*p_direction); } - StartActionIfUnknown0x13c(action); + StartActionIfInitialized(action); } else { MxMatrix matrix; diff --git a/LEGO1/lego/legoomni/src/worlds/police.cpp b/LEGO1/lego/legoomni/src/worlds/police.cpp index 16297b76..e609b319 100644 --- a/LEGO1/lego/legoomni/src/worlds/police.cpp +++ b/LEGO1/lego/legoomni/src/worlds/police.cpp @@ -101,7 +101,7 @@ void Police::ReadyWorld() // FUNCTION: LEGO1 0x1005e550 MxLong Police::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case PoliceScript::c_LeftArrow_Ctl: case PoliceScript::c_RightArrow_Ctl: diff --git a/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp b/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp index 709b338d..28407834 100644 --- a/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp +++ b/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp @@ -241,7 +241,7 @@ MxLong RegistrationBook::HandleKeyPress(SDL_Keycode p_key) // FUNCTION: LEGO1 0x100774a0 MxLong RegistrationBook::HandleControl(LegoControlManagerNotificationParam& p_param) { - MxS16 buttonId = p_param.m_unk0x28; + MxS16 buttonId = p_param.m_enabledChild; const InternationalCharacter* intChar = NULL; for (int i = 0; i < sizeOfArray(m_intAlphabet); i++) { @@ -262,10 +262,10 @@ MxLong RegistrationBook::HandleControl(LegoControlManagerNotificationParam& p_pa DeleteObjects(&m_atomId, RegbookScript::c_iic006in_RunAnim, RegbookScript::c_iic008in_PlayWav); if (GameState()->GetCurrentAct() == LegoGameState::e_act1) { - m_infocenterState->m_unk0x74 = 15; + m_infocenterState->m_state = InfocenterState::e_backToInfoAct1; } else { - m_infocenterState->m_unk0x74 = 2; + m_infocenterState->m_state = InfocenterState::e_notRegistered; } TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); @@ -355,7 +355,7 @@ void RegistrationBook::FUN_100775c0(MxS16 p_playerIndex) break; } - m_infocenterState->m_unk0x74 = 4; + m_infocenterState->m_state = InfocenterState::e_selectedSave; if (m_unk0x2b8 == 0 && !m_unk0x2c1) { DeleteObjects(&m_atomId, RegbookScript::c_iic006in_RunAnim, RegbookScript::c_iic008in_PlayWav); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); @@ -682,12 +682,12 @@ MxBool RegistrationBook::CreateSurface() } if (presenter) { - m_checkboxSurface = presenter->VTable0x78(); + m_checkboxSurface = presenter->GetSurface(); } presenter = (MxStillPresenter*) Find("MxStillPresenter", "CheckHiLite_Bitmap"); if (presenter) { - m_checkboxHilite = presenter->VTable0x78(); + m_checkboxHilite = presenter->GetSurface(); } if (m_checkboxSurface && m_checkboxHilite) { diff --git a/LEGO1/lego/legoomni/src/worlds/score.cpp b/LEGO1/lego/legoomni/src/worlds/score.cpp index 14b91a18..067f43e4 100644 --- a/LEGO1/lego/legoomni/src/worlds/score.cpp +++ b/LEGO1/lego/legoomni/src/worlds/score.cpp @@ -165,7 +165,7 @@ void Score::ReadyWorld() // FUNCTION: LEGO1 0x100016d0 MxLong Score::FUN_100016d0(LegoControlManagerNotificationParam& p_param) { - MxS16 unk0x28 = p_param.m_unk0x28; + MxS16 unk0x28 = p_param.m_enabledChild; if (unk0x28 == 1 || p_param.m_clickedObjectId == InfoscorScript::c_LegoBox_Ctl) { switch (p_param.m_clickedObjectId) { diff --git a/LEGO1/lego/sources/anim/legoanim.cpp b/LEGO1/lego/sources/anim/legoanim.cpp index 9026c245..e0fb90b6 100644 --- a/LEGO1/lego/sources/anim/legoanim.cpp +++ b/LEGO1/lego/sources/anim/legoanim.cpp @@ -10,20 +10,20 @@ DECOMP_SIZE_ASSERT(LegoTranslationKey, 0x14) DECOMP_SIZE_ASSERT(LegoRotationKey, 0x18) DECOMP_SIZE_ASSERT(LegoScaleKey, 0x14) DECOMP_SIZE_ASSERT(LegoMorphKey, 0x0c) -DECOMP_SIZE_ASSERT(LegoUnknownKey, 0x0c) +DECOMP_SIZE_ASSERT(LegoRotationZKey, 0x0c) DECOMP_SIZE_ASSERT(LegoAnimNodeData, 0x34) DECOMP_SIZE_ASSERT(LegoAnimActorEntry, 0x08) DECOMP_SIZE_ASSERT(LegoAnimScene, 0x24) DECOMP_SIZE_ASSERT(LegoAnim, 0x18) // FUNCTION: LEGO1 0x1009f000 -LegoUnknownKey::LegoUnknownKey() +LegoRotationZKey::LegoRotationZKey() { m_z = 0.0f; } // FUNCTION: LEGO1 0x1009f020 -LegoResult LegoUnknownKey::Read(LegoStorage* p_storage) +LegoResult LegoRotationZKey::Read(LegoStorage* p_storage) { LegoResult result; @@ -40,7 +40,7 @@ LegoResult LegoUnknownKey::Read(LegoStorage* p_storage) // FUNCTION: LEGO1 0x1009f060 // FUNCTION: BETA10 0x1018133f -LegoResult LegoUnknownKey::Write(LegoStorage* p_storage) +LegoResult LegoRotationZKey::Write(LegoStorage* p_storage) { LegoResult result; @@ -58,33 +58,33 @@ LegoResult LegoUnknownKey::Write(LegoStorage* p_storage) // FUNCTION: LEGO1 0x1009f0a0 LegoAnimScene::LegoAnimScene() { - m_unk0x00 = 0; - m_unk0x04 = NULL; - m_unk0x08 = 0; - m_unk0x0c = NULL; - m_unk0x10 = 0; - m_unk0x14 = NULL; - m_unk0x18 = 0; - m_unk0x1c = 0; - m_unk0x20 = 0; + m_translationKeysCount = 0; + m_translationKeys = NULL; + m_targetKeysCount = 0; + m_targetKeys = NULL; + m_rotationKeysCount = 0; + m_rotationKeys = NULL; + m_targetIndex = 0; + m_translationIndex = 0; + m_rotationIndex = 0; } // FUNCTION: LEGO1 0x1009f0d0 LegoAnimScene::~LegoAnimScene() { - if (m_unk0x04 != NULL) { - delete[] m_unk0x04; - m_unk0x04 = NULL; + if (m_translationKeys != NULL) { + delete[] m_translationKeys; + m_translationKeys = NULL; } - if (m_unk0x0c != NULL) { - delete[] m_unk0x0c; - m_unk0x0c = NULL; + if (m_targetKeys != NULL) { + delete[] m_targetKeys; + m_targetKeys = NULL; } - if (m_unk0x14 != NULL) { - delete[] m_unk0x14; - m_unk0x14 = NULL; + if (m_rotationKeys != NULL) { + delete[] m_rotationKeys; + m_rotationKeys = NULL; } } @@ -95,34 +95,34 @@ LegoResult LegoAnimScene::Write(LegoStorage* p_storage) LegoResult result; LegoS32 i; - if ((result = p_storage->Write(&m_unk0x00, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Write(&m_translationKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x00 != 0) { - for (i = 0; i < m_unk0x00; i++) { - if ((result = m_unk0x04[i].Write(p_storage)) != SUCCESS) { + if (m_translationKeysCount != 0) { + for (i = 0; i < m_translationKeysCount; i++) { + if ((result = m_translationKeys[i].Write(p_storage)) != SUCCESS) { return result; } } } - if ((result = p_storage->Write(&m_unk0x08, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Write(&m_targetKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x08 != 0) { - for (i = 0; i < m_unk0x08; i++) { - if ((result = m_unk0x0c[i].Write(p_storage)) != SUCCESS) { + if (m_targetKeysCount != 0) { + for (i = 0; i < m_targetKeysCount; i++) { + if ((result = m_targetKeys[i].Write(p_storage)) != SUCCESS) { return result; } } } - if ((result = p_storage->Write(&m_unk0x10, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Write(&m_rotationKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x10 != 0) { - for (i = 0; i < m_unk0x10; i++) { - if ((result = m_unk0x14[i].Write(p_storage)) != SUCCESS) { + if (m_rotationKeysCount != 0) { + for (i = 0; i < m_rotationKeysCount; i++) { + if ((result = m_rotationKeys[i].Write(p_storage)) != SUCCESS) { return result; } } @@ -137,37 +137,37 @@ LegoResult LegoAnimScene::Read(LegoStorage* p_storage) LegoResult result; LegoS32 i; - if ((result = p_storage->Read(&m_unk0x00, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Read(&m_translationKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x00 != 0) { - m_unk0x04 = new LegoTranslationKey[m_unk0x00]; - for (i = 0; i < m_unk0x00; i++) { - if ((result = m_unk0x04[i].Read(p_storage)) != SUCCESS) { + if (m_translationKeysCount != 0) { + m_translationKeys = new LegoTranslationKey[m_translationKeysCount]; + for (i = 0; i < m_translationKeysCount; i++) { + if ((result = m_translationKeys[i].Read(p_storage)) != SUCCESS) { goto done; } } } - if ((result = p_storage->Read(&m_unk0x08, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Read(&m_targetKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x08 != 0) { - m_unk0x0c = new LegoTranslationKey[m_unk0x08]; - for (i = 0; i < m_unk0x08; i++) { - if ((result = m_unk0x0c[i].Read(p_storage)) != SUCCESS) { + if (m_targetKeysCount != 0) { + m_targetKeys = new LegoTranslationKey[m_targetKeysCount]; + for (i = 0; i < m_targetKeysCount; i++) { + if ((result = m_targetKeys[i].Read(p_storage)) != SUCCESS) { goto done; } } } - if ((result = p_storage->Read(&m_unk0x10, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Read(&m_rotationKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x10 != 0) { - m_unk0x14 = new LegoUnknownKey[m_unk0x10]; - for (i = 0; i < m_unk0x10; i++) { - if ((result = m_unk0x14[i].Read(p_storage)) != SUCCESS) { + if (m_rotationKeysCount != 0) { + m_rotationKeys = new LegoRotationZKey[m_rotationKeysCount]; + for (i = 0; i < m_rotationKeysCount; i++) { + if ((result = m_rotationKeys[i].Read(p_storage)) != SUCCESS) { goto done; } } @@ -176,22 +176,22 @@ LegoResult LegoAnimScene::Read(LegoStorage* p_storage) return SUCCESS; done: - if (m_unk0x04 != NULL) { - delete[] m_unk0x04; - m_unk0x00 = 0; - m_unk0x04 = NULL; + if (m_translationKeys != NULL) { + delete[] m_translationKeys; + m_translationKeysCount = 0; + m_translationKeys = NULL; } - if (m_unk0x0c != NULL) { - delete[] m_unk0x0c; - m_unk0x08 = 0; - m_unk0x0c = NULL; + if (m_targetKeys != NULL) { + delete[] m_targetKeys; + m_targetKeysCount = 0; + m_targetKeys = NULL; } - if (m_unk0x14 != NULL) { - delete[] m_unk0x14; - m_unk0x10 = 0; - m_unk0x14 = NULL; + if (m_rotationKeys != NULL) { + delete[] m_rotationKeys; + m_rotationKeysCount = 0; + m_rotationKeys = NULL; } return result; @@ -199,82 +199,95 @@ LegoResult LegoAnimScene::Read(LegoStorage* p_storage) // FUNCTION: LEGO1 0x1009f490 // FUNCTION: BETA10 0x10181a83 -LegoResult LegoAnimScene::FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix) +LegoResult LegoAnimScene::CalculateCameraTransform(LegoFloat p_time, Matrix4& p_matrix) { - MxMatrix localb0; - MxMatrix local4c; + MxMatrix tempMatrix; + MxMatrix original; - Vector3 local5c(localb0[0]); - Vector3 local68(localb0[1]); - Vector3 local54(localb0[2]); - Vector3 localb8(localb0[3]); + Vector3 column0(tempMatrix[0]); + Vector3 column1(tempMatrix[1]); + Vector3 column2(tempMatrix[2]); + Vector3 column3(tempMatrix[3]); - Mx3DPointFloat localcc; + Mx3DPointFloat tempTranslation; - localb0.SetIdentity(); + tempMatrix.SetIdentity(); - LegoU32 local60; - if (m_unk0x08 != 0) { - local60 = GetUnknown0x18(); - LegoAnimNodeData::GetTranslation(m_unk0x08, m_unk0x0c, p_time, localb0, local60); - SetUnknown0x18(local60); - localcc = localb8; - localb8.Clear(); + LegoU32 translationIndex; + if (m_targetKeysCount != 0) { + translationIndex = GetTargetIndex(); + LegoAnimNodeData::GetTranslation(m_targetKeysCount, m_targetKeys, p_time, tempMatrix, translationIndex); + SetTargetIndex(translationIndex); + tempTranslation = column3; + column3.Clear(); } - if (m_unk0x00 != 0) { - local60 = GetUnknown0x1c(); - LegoAnimNodeData::GetTranslation(m_unk0x00, m_unk0x04, p_time, localb0, local60); - SetUnknown0x1c(local60); + if (m_translationKeysCount != 0) { + translationIndex = GetTranslationIndex(); + LegoAnimNodeData::GetTranslation( + m_translationKeysCount, + m_translationKeys, + p_time, + tempMatrix, + translationIndex + ); + SetTranslationIndex(translationIndex); } - local54 = localcc; - local54 -= localb8; + column2 = tempTranslation; + column2 -= column3; - if (local54.Unitize() == 0) { - local5c.EqualsCross(local68, local54); + if (column2.Unitize() == 0) { + column0.EqualsCross(column1, column2); - if (local5c.Unitize() == 0) { - local68.EqualsCross(local54, local5c); + if (column0.Unitize() == 0) { + column1.EqualsCross(column2, column0); - localcc = p_matrix[3]; - localcc += localb0[3]; + tempTranslation = p_matrix[3]; + tempTranslation += tempMatrix[3]; - p_matrix[3][0] = p_matrix[3][1] = p_matrix[3][2] = localb0[3][0] = localb0[3][1] = localb0[3][2] = 0; + p_matrix[3][0] = p_matrix[3][1] = p_matrix[3][2] = tempMatrix[3][0] = tempMatrix[3][1] = tempMatrix[3][2] = + 0; - if (m_unk0x10 != 0) { - LegoU32 locald0 = -1; - LegoU32 locald8; - locald0 = GetUnknown0x20(); + if (m_rotationKeysCount != 0) { + LegoU32 old_index = -1; + LegoU32 i; + old_index = GetRotationIndex(); - LegoU32 localdc = - LegoAnimNodeData::FindKeys(p_time, m_unk0x10, m_unk0x14, sizeof(*m_unk0x14), locald8, locald0); + LegoU32 count = LegoAnimNodeData::FindKeys( + p_time, + m_rotationKeysCount, + m_rotationKeys, + sizeof(*m_rotationKeys), + i, + old_index + ); - SetUnknown0x20(locald0); + SetRotationIndex(old_index); - switch (localdc) { + switch (count) { case 1: - p_matrix.RotateZ(m_unk0x14[locald8].GetZ()); + p_matrix.RotateZ(m_rotationKeys[i].GetZ()); break; case 2: // Seems to be unused LegoFloat z = LegoAnimNodeData::Interpolate( p_time, - m_unk0x14[locald8], - m_unk0x14[locald8].GetZ(), - m_unk0x14[locald8 + 1], - m_unk0x14[locald8 + 1].GetZ() + m_rotationKeys[i], + m_rotationKeys[i].GetZ(), + m_rotationKeys[i + 1], + m_rotationKeys[i + 1].GetZ() ); - p_matrix.RotateZ(m_unk0x14[locald8].GetZ()); + p_matrix.RotateZ(m_rotationKeys[i].GetZ()); break; } } - local4c = p_matrix; - p_matrix.Product(local4c.GetData(), localb0.GetData()); - p_matrix[3][0] = localcc[0]; - p_matrix[3][1] = localcc[1]; - p_matrix[3][2] = localcc[2]; + original = p_matrix; + p_matrix.Product(original.GetData(), tempMatrix.GetData()); + p_matrix[3][0] = tempTranslation[0]; + p_matrix[3][1] = tempTranslation[1]; + p_matrix[3][2] = tempTranslation[2]; } } diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index 7a03d99c..1c297c4d 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -137,9 +137,9 @@ class LegoMorphKey : public LegoAnimKey { }; // SIZE 0x0c -class LegoUnknownKey : public LegoAnimKey { +class LegoRotationZKey : public LegoAnimKey { public: - LegoUnknownKey(); + LegoRotationZKey(); LegoResult Read(LegoStorage* p_storage); LegoResult Write(LegoStorage* p_storage); @@ -309,26 +309,26 @@ class LegoAnimScene { ~LegoAnimScene(); LegoResult Read(LegoStorage* p_storage); LegoResult Write(LegoStorage* p_storage); - LegoResult FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix); + LegoResult CalculateCameraTransform(LegoFloat p_time, Matrix4& p_matrix); - LegoU32 GetUnknown0x18() { return m_unk0x18; } - LegoU32 GetUnknown0x1c() { return m_unk0x1c; } - LegoU32 GetUnknown0x20() { return m_unk0x20; } + LegoU32 GetTargetIndex() { return m_targetIndex; } + LegoU32 GetTranslationIndex() { return m_translationIndex; } + LegoU32 GetRotationIndex() { return m_rotationIndex; } - void SetUnknown0x18(LegoU32 p_unk0x18) { m_unk0x18 = p_unk0x18; } - void SetUnknown0x1c(LegoU32 p_unk0x1c) { m_unk0x1c = p_unk0x1c; } - void SetUnknown0x20(LegoU32 p_unk0x20) { m_unk0x20 = p_unk0x20; } + void SetTargetIndex(LegoU32 p_targetIndex) { m_targetIndex = p_targetIndex; } + void SetTranslationIndex(LegoU32 p_translationIndex) { m_translationIndex = p_translationIndex; } + void SetRotationIndex(LegoU32 p_rotationIndex) { m_rotationIndex = p_rotationIndex; } private: - LegoU16 m_unk0x00; // 0x00 - LegoTranslationKey* m_unk0x04; // 0x04 - LegoU16 m_unk0x08; // 0x08 - LegoTranslationKey* m_unk0x0c; // 0x0c - LegoU16 m_unk0x10; // 0x10 - LegoUnknownKey* m_unk0x14; // 0x14 - LegoU32 m_unk0x18; // 0x18 - LegoU32 m_unk0x1c; // 0x1c - LegoU32 m_unk0x20; // 0x20 + LegoU16 m_translationKeysCount; // 0x00 + LegoTranslationKey* m_translationKeys; // 0x04 + LegoU16 m_targetKeysCount; // 0x08 + LegoTranslationKey* m_targetKeys; // 0x0c + LegoU16 m_rotationKeysCount; // 0x10 + LegoRotationZKey* m_rotationKeys; // 0x14 + LegoU32 m_targetIndex; // 0x18 + LegoU32 m_translationIndex; // 0x1c + LegoU32 m_rotationIndex; // 0x20 }; // VTABLE: LEGO1 0x100db8d8 diff --git a/LEGO1/lego/sources/geom/legoweedge.cpp b/LEGO1/lego/sources/geom/legoweedge.cpp index be522c4c..967e55ce 100644 --- a/LEGO1/lego/sources/geom/legoweedge.cpp +++ b/LEGO1/lego/sources/geom/legoweedge.cpp @@ -12,6 +12,7 @@ LegoWEEdge::LegoWEEdge() } // FUNCTION: LEGO1 0x1009a590 +// FUNCTION: BETA10 0x10182530 LegoWEEdge::~LegoWEEdge() { if (m_edges) { @@ -20,31 +21,52 @@ LegoWEEdge::~LegoWEEdge() } // FUNCTION: LEGO1 0x1009a5b0 +// FUNCTION: BETA10 0x10182577 LegoS32 LegoWEEdge::LinkEdgesAndFaces() { + assert(m_edges); + assert(m_numEdges); + for (LegoS32 i = 0; i < m_numEdges; i++) { LegoOrientedEdge* e1 = m_edges[i]; - LegoOrientedEdge* e2 = (m_numEdges - i) == 1 ? m_edges[0] : m_edges[i + 1]; + LegoOrientedEdge* e2 = (m_numEdges - 1) == i ? m_edges[0] : m_edges[i + 1]; if (e2->m_pointA == e1->m_pointA) { + assert(e1->m_faceA == NULL || e1->m_faceA == this); + assert(e2->m_faceB == NULL || e2->m_faceB == this); + assert(e1->m_ccwA == NULL || e1->m_ccwA == e2); + assert(e2->m_cwB == NULL || e2->m_cwB == e1); e1->m_faceA = this; e2->m_faceB = this; e1->m_ccwA = e2; e2->m_cwB = e1; } else if (e2->m_pointB == e1->m_pointA) { + assert(e1->m_faceA == NULL || e1->m_faceA == this); + assert(e2->m_faceA == NULL || e2->m_faceA == this); + assert(e1->m_ccwA == NULL || e1->m_ccwA == e2); + assert(e2->m_cwA == NULL || e2->m_cwA == e1); e1->m_faceA = this; e2->m_faceA = this; e1->m_ccwA = e2; e2->m_cwA = e1; } else if (e1->m_pointB == e2->m_pointA) { + assert(e1->m_faceB == NULL || e1->m_faceB == this); + assert(e2->m_faceB == NULL || e2->m_faceB == this); + assert(e1->m_ccwB == NULL || e1->m_ccwB == e2); + assert(e2->m_cwB == NULL || e2->m_cwB == e1); e1->m_faceB = this; e2->m_faceB = this; e1->m_ccwB = e2; e2->m_cwB = e1; } else { + assert(e1->m_pointB == e2->m_pointB); + assert(e1->m_faceB == NULL || e1->m_faceB == this); + assert(e2->m_faceA == NULL || e2->m_faceA == this); + assert(e1->m_ccwB == NULL || e1->m_ccwB == e2); + assert(e2->m_cwA == NULL || e2->m_cwA == e1); e1->m_faceB = this; e2->m_faceA = this; e1->m_ccwB = e2; diff --git a/LEGO1/lego/sources/geom/legoweedge.h b/LEGO1/lego/sources/geom/legoweedge.h index 7e0e9bae..2681c370 100644 --- a/LEGO1/lego/sources/geom/legoweedge.h +++ b/LEGO1/lego/sources/geom/legoweedge.h @@ -6,8 +6,8 @@ struct LegoOrientedEdge; -// might be a struct with public members // VTABLE: LEGO1 0x100db7c0 +// VTABLE: BETA10 0x101c3730 // SIZE 0x0c class LegoWEEdge { public: @@ -33,6 +33,7 @@ class LegoWEEdge { } // SYNTHETIC: LEGO1 0x1009a570 + // SYNTHETIC: BETA10 0x10182b70 // LegoWEEdge::`scalar deleting destructor' protected: diff --git a/LEGO1/lego/sources/geom/legowegedge.cpp b/LEGO1/lego/sources/geom/legowegedge.cpp index df37ab12..ae12c8ee 100644 --- a/LEGO1/lego/sources/geom/legowegedge.cpp +++ b/LEGO1/lego/sources/geom/legowegedge.cpp @@ -22,6 +22,7 @@ LegoWEGEdge::LegoWEGEdge() } // FUNCTION: LEGO1 0x1009a800 +// FUNCTION: BETA10 0x101831bd LegoWEGEdge::~LegoWEGEdge() { if (m_edges) { diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index c2929079..ea9fab08 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -29,6 +29,7 @@ struct PathWithTrigger { // might be a struct with public members // VTABLE: LEGO1 0x100db7f8 +// VTABLE: BETA10 0x101c3798 // SIZE 0x54 class LegoWEGEdge : public LegoWEEdge { public: @@ -80,6 +81,7 @@ class LegoWEGEdge : public LegoWEEdge { LegoU8 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); } // SYNTHETIC: LEGO1 0x1009a7e0 + // SYNTHETIC: BETA10 0x10184130 // LegoWEGEdge::`scalar deleting destructor' friend class LegoPathController; diff --git a/LEGO1/lego/sources/misc/legocontainer.h b/LEGO1/lego/sources/misc/legocontainer.h index fd439912..a7ab0068 100644 --- a/LEGO1/lego/sources/misc/legocontainer.h +++ b/LEGO1/lego/sources/misc/legocontainer.h @@ -122,6 +122,10 @@ class LegoTextureContainer : public LegoContainer { LegoTextureInfo* GetCached(LegoTextureInfo* p_textureInfo); void EraseCached(LegoTextureInfo* p_textureInfo); + // Verified by LegoOmni::Create(), even though there have been significant changes. + // SYNTHETIC: BETA10 0x10093ea0 + // LegoTextureContainer::LegoTextureContainer + protected: LegoCachedTextureList m_cached; // 0x18 }; diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index 7b02dd01..4ebe1f5f 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -115,7 +115,7 @@ LegoROI::~LegoROI() // FUNCTION: LEGO1 0x100a84a0 // FUNCTION: BETA10 0x10189b99 LegoResult LegoROI::Read( - OrientableROI* p_unk0xd4, + OrientableROI* p_parentROI, Tgl::Renderer* p_renderer, ViewLODListManager* p_viewLODListManager, LegoTextureContainer* p_textureContainer, @@ -135,7 +135,7 @@ LegoResult LegoROI::Read( LegoSphere sphere; LegoBox box; - m_parentROI = p_unk0xd4; + m_parentROI = p_parentROI; if (p_storage->Read(&length, sizeof(LegoU32)) != SUCCESS) { goto done; @@ -178,11 +178,11 @@ LegoResult LegoROI::Read( textureName = NULL; } - if (p_storage->Read(&m_unk0x100, sizeof(undefined)) != SUCCESS) { + if (p_storage->Read(&m_sharedLodList, sizeof(LegoBool)) != SUCCESS) { goto done; } - if (m_unk0x100) { + if (m_sharedLodList) { for (roiLength = strlen(m_name); roiLength; roiLength--) { if (m_name[roiLength - 1] < '0' || m_name[roiLength - 1] > '9') { break; @@ -390,7 +390,7 @@ LegoROI* LegoROI::FindChildROI(const LegoChar* p_name, LegoROI* p_roi) // FUNCTION: LEGO1 0x100a8da0 // FUNCTION: BETA10 0x1018a9fb -LegoResult LegoROI::ApplyAnimationTransformation( +LegoResult LegoROI::ApplyChildAnimationTransformation( LegoTreeNode* p_node, const Matrix4& p_matrix, LegoTime p_time, @@ -411,15 +411,19 @@ LegoResult LegoROI::ApplyAnimationTransformation( roi->m_local2world.Product(mat, p_matrix); roi->UpdateWorldData(); - LegoBool und = data->GetVisibility(p_time); - roi->SetVisibility(und); + roi->SetVisibility(data->GetVisibility(p_time)); for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) { - ApplyAnimationTransformation(p_node->GetChild(i), roi->m_local2world, p_time, roi); + ApplyChildAnimationTransformation(p_node->GetChild(i), roi->m_local2world, p_time, roi); } } else { FUN_100a81b0("%s ROI Not found\n", name); +#ifdef BETA10 + _RPT1(_CRT_ASSERT, "%s ROI Not Found", name); + // Note that the macro inserts an INT3, which breaks the assumption that INT3 + // only occurs as a filler for empty space in the binary. +#endif } return SUCCESS; @@ -427,7 +431,7 @@ LegoResult LegoROI::ApplyAnimationTransformation( // FUNCTION: LEGO1 0x100a8e80 // FUNCTION: BETA10 0x1018ab3a -void LegoROI::FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap) +void LegoROI::ApplyAnimationTransformation(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap) { MxMatrix mat; @@ -439,11 +443,11 @@ void LegoROI::FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_t roi->m_local2world.Product(mat, p_matrix); roi->UpdateWorldData(); - LegoBool und = data->GetVisibility(p_time); - roi->SetVisibility(und); + LegoBool visiblity = data->GetVisibility(p_time); + roi->SetVisibility(visiblity); for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) { - FUN_100a8e80(p_node->GetChild(i), roi->m_local2world, p_time, p_roiMap); + ApplyAnimationTransformation(p_node->GetChild(i), roi->m_local2world, p_time, p_roiMap); } } else { @@ -451,14 +455,14 @@ void LegoROI::FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_t local2world.Product(mat, p_matrix); for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) { - FUN_100a8e80(p_node->GetChild(i), local2world, p_time, p_roiMap); + ApplyAnimationTransformation(p_node->GetChild(i), local2world, p_time, p_roiMap); } } } // FUNCTION: LEGO1 0x100a8fd0 // FUNCTION: BETA10 0x1018ac81 -void LegoROI::FUN_100a8fd0(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap) +void LegoROI::ApplyTransform(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap) { MxMatrix mat; @@ -470,7 +474,7 @@ void LegoROI::FUN_100a8fd0(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_t roi->m_local2world.Product(mat, p_matrix); for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) { - FUN_100a8fd0(p_node->GetChild(i), roi->m_local2world, p_time, p_roiMap); + ApplyTransform(p_node->GetChild(i), roi->m_local2world, p_time, p_roiMap); } } else { @@ -478,7 +482,7 @@ void LegoROI::FUN_100a8fd0(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_t local2world.Product(mat, p_matrix); for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) { - FUN_100a8fd0(p_node->GetChild(i), local2world, p_time, p_roiMap); + ApplyTransform(p_node->GetChild(i), local2world, p_time, p_roiMap); } } } @@ -493,7 +497,7 @@ LegoResult LegoROI::SetFrame(LegoAnim* p_anim, LegoTime p_time) mat = m_local2world; mat.SetIdentity(); // this clears the matrix, assignment above is redundant - return ApplyAnimationTransformation(root, mat, p_time, this); + return ApplyChildAnimationTransformation(root, mat, p_time, this); } // FUNCTION: LEGO1 0x100a9170 @@ -756,7 +760,7 @@ TimeROI::TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_t // FUNCTION: LEGO1 0x100a9b40 // FUNCTION: BETA10 0x1018bbf0 -void TimeROI::FUN_100a9b40(Matrix4& p_matrix, LegoTime p_time) +void TimeROI::CalculateWorldVelocity(Matrix4& p_matrix, LegoTime p_time) { LegoTime time = p_time - m_time; diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index bef2c580..00452334 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -27,21 +27,26 @@ class LegoROI : public ViewROI { ~LegoROI() override; LegoResult Read( - OrientableROI* p_unk0xd4, + OrientableROI* p_parentROI, Tgl::Renderer* p_renderer, ViewLODListManager* p_viewLODListManager, LegoTextureContainer* p_textureContainer, LegoStorage* p_storage ); LegoROI* FindChildROI(const LegoChar* p_name, LegoROI* p_roi); - LegoResult ApplyAnimationTransformation( + LegoResult ApplyChildAnimationTransformation( LegoTreeNode* p_node, const Matrix4& p_matrix, LegoTime p_time, LegoROI* p_roi ); - static void FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap); - static void FUN_100a8fd0(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap); + static void ApplyAnimationTransformation( + LegoTreeNode* p_node, + Matrix4& p_matrix, + LegoTime p_time, + LegoROI** p_roiMap + ); + static void ApplyTransform(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap); LegoResult SetFrame(LegoAnim* p_anim, LegoTime p_time); LegoResult SetLodColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha); LegoResult SetTextureInfo(LegoTextureInfo* p_textureInfo); @@ -92,10 +97,10 @@ class LegoROI : public ViewROI { // LegoROI::`scalar deleting destructor' private: - LegoChar* m_name; // 0xe4 - BoundingSphere m_sphere; // 0xe8 - undefined m_unk0x100; // 0x100 - LegoEntity* m_entity; // 0x104 + LegoChar* m_name; // 0xe4 + BoundingSphere m_sphere; // 0xe8 + LegoBool m_sharedLodList; // 0x100 + LegoEntity* m_entity; // 0x104 friend class DebugViewer; }; @@ -107,7 +112,7 @@ class TimeROI : public LegoROI { public: TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_time); - void FUN_100a9b40(Matrix4& p_matrix, LegoTime p_time); + void CalculateWorldVelocity(Matrix4& p_matrix, LegoTime p_time); // SYNTHETIC: LEGO1 0x100a9ad0 // SYNTHETIC: BETA10 0x1018c540 diff --git a/LEGO1/lego1_pch.h b/LEGO1/lego1_pch.h index 624a4be3..0797d498 100644 --- a/LEGO1/lego1_pch.h +++ b/LEGO1/lego1_pch.h @@ -87,13 +87,10 @@ #include "lego/legoomni/include/legoextraactor.h" #include "lego/legoomni/include/legoflctexturepresenter.h" #include "lego/legoomni/include/legogamestate.h" -#include "lego/legoomni/include/legohideanimpresenter.h" #include "lego/legoomni/include/legoinputmanager.h" #include "lego/legoomni/include/legoloadcachesoundpresenter.h" #include "lego/legoomni/include/legolocations.h" -#include "lego/legoomni/include/legolocomotionanimpresenter.h" #include "lego/legoomni/include/legolodlist.h" -#include "lego/legoomni/include/legoloopinganimpresenter.h" #include "lego/legoomni/include/legomain.h" #include "lego/legoomni/include/legometerpresenter.h" #include "lego/legoomni/include/legomodelpresenter.h" @@ -239,7 +236,7 @@ #include "omni/include/mxlist.h" #include "omni/include/mxloopingflcpresenter.h" #include "omni/include/mxloopingsmkpresenter.h" -#include "omni/include/mxmediamanager.h" +#include "omni/include/mxmain.h" #include "omni/include/mxmediapresenter.h" #include "omni/include/mxmemorypool.h" #include "omni/include/mxmisc.h" @@ -247,11 +244,11 @@ #include "omni/include/mxnotificationmanager.h" #include "omni/include/mxnotificationparam.h" #include "omni/include/mxobjectfactory.h" -#include "omni/include/mxomni.h" #include "omni/include/mxomnicreateflags.h" #include "omni/include/mxomnicreateparam.h" #include "omni/include/mxpalette.h" #include "omni/include/mxparam.h" +#include "omni/include/mxpresentationmanager.h" #include "omni/include/mxpresenter.h" #include "omni/include/mxpresenterlist.h" #include "omni/include/mxqueue.h" diff --git a/LEGO1/library_msvc.h b/LEGO1/library_msvc.h index 96437e7a..dfd217d4 100644 --- a/LEGO1/library_msvc.h +++ b/LEGO1/library_msvc.h @@ -132,9 +132,11 @@ // ??_L@YGXPAXIHP6EX0@Z1@Z // LIBRARY: LEGO1 0x1008c2e0 +// LIBRARY: BETA10 0x100f9800 // ??_M@YGXPAXIHP6EX0@Z@Z // LIBRARY: LEGO1 0x1008c370 +// LIBRARY: BETA10 0x100f98b0 // ?__ArrayUnwind@@YGXPAXIHP6EX0@Z@Z // LIBRARY: LEGO1 0x1008c410 @@ -162,6 +164,7 @@ // __amsg_exit // LIBRARY: LEGO1 0x1008c980 +// LIBRARY: BETA10 0x10101318 // __except_handler3 // LIBRARY: LEGO1 0x1008ca60 @@ -780,6 +783,64 @@ // LIBRARY: BETA10 0x100fa200 // strcpy +// LIBRARY: BETA10 0x100fa210 +// strcat + +// LIBRARY: BETA10 0x100fed20 +// strncat + +// LIBRARY: BETA10 0x100faab0 +// strncpy + +// LIBRARY: BETA10 0x100ff490 +// setvbuf + +// LIBRARY: BETA10 0x100ff180 +// fflush + +// LIBRARY: BETA10 0x100fec40 +// __crtMessageBoxA + +// LIBRARY: BETA10 0x100fee50 +// _itoa + +// LIBRARY: BETA10 0x10106f70 +// _lock_file + +// LIBRARY: BETA10 0x100ff1e0 +// _fflush_lk + +// LIBRARY: BETA10 0x10107010 +// _unlock_file + +// LIBRARY: BETA10 0x10106ea0 +// _lock + +// LIBRARY: BETA10 0x10106f50 +// _unlock + +// LIBRARY: BETA10 0x100fdaf0 +// _getptd + +// LIBRARY: BETA10 0x10104040 +// _malloc_dbg + +// GLOBAL: BETA10 0x101fb7b0 +// _locktable + +// LIBRARY: BETA10 0x10104c00 +// _free_dbg + +// LIBRARY: BETA10 0x100fe900 +// raise + +// GLOBAL: BETA10 0x101fa950 +// _iob + +// GLOBAL: BETA10 0x102122d0 +// _bufin + + // LIBRARY: BETA10 0x100f8a88 // ??2@YAPAXI@Z diff --git a/LEGO1/mxdirectx/mxdirect3d.cpp b/LEGO1/mxdirectx/mxdirect3d.cpp index 7f12d147..84ff77d3 100644 --- a/LEGO1/mxdirectx/mxdirect3d.cpp +++ b/LEGO1/mxdirectx/mxdirect3d.cpp @@ -1,7 +1,12 @@ +#ifndef MINIWIN +#include +#endif + #include "mxdirect3d.h" #include // for SDL_Log #include +#include DECOMP_SIZE_ASSERT(MxDirect3D, 0x894) @@ -44,6 +49,7 @@ BOOL MxDirect3D::Create( ) { BOOL success = FALSE; + IDirect3DMiniwin* miniwind3d = nullptr; assert(m_currentDeviceInfo); if (!MxDirectDraw::Create( @@ -64,6 +70,21 @@ BOOL MxDirect3D::Create( goto done; } + if (m_pDirect3d->QueryInterface(IID_IDirect3DMiniwin, (void**) &miniwind3d) == DD_OK) { + MxVideoParam* videoParam = (MxVideoParam*) SDL_GetPointerProperty( + SDL_GetWindowProperties(reinterpret_cast(hWnd)), + ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM, + nullptr + ); +#ifndef MXDIRECTX_FOR_CONFIG + assert(videoParam); +#endif + if (videoParam) { + miniwind3d->RequestMSAA(videoParam->GetMSAASamples()); + miniwind3d->RequestAnisotropic(videoParam->GetAnisotropic()); + } + } + if (!D3DSetMode()) { goto done; } diff --git a/LEGO1/mxdirectx/mxdirectxinfo.cpp b/LEGO1/mxdirectx/mxdirectxinfo.cpp index 3451b8fc..765d32f7 100644 --- a/LEGO1/mxdirectx/mxdirectxinfo.cpp +++ b/LEGO1/mxdirectx/mxdirectxinfo.cpp @@ -1,7 +1,10 @@ #include "mxdirectxinfo.h" +#include "omni/include/mxvideoparam.h" + #include #include +#include #include // for vsprintf DECOMP_SIZE_ASSERT(MxAssignedDevice, 0xe4) @@ -216,12 +219,29 @@ BOOL MxDeviceEnumerate::EnumDirectDrawCallback(LPGUID p_guid, LPSTR p_driverDesc LPDIRECTDRAW lpDD = NULL; MxDriver& newDevice = m_ddInfo.back(); HRESULT result = DirectDrawCreate(newDevice.m_guid, &lpDD, NULL); + IDirect3DMiniwin* miniwind3d = nullptr; if (result != DD_OK) { BuildErrorString("DirectDraw Create failed: %s\n", EnumerateErrorToString(result)); goto done; } + result = lpDD->QueryInterface(IID_IDirect3DMiniwin, (void**) &miniwind3d); + if (result == DD_OK) { + MxVideoParam* videoParam = (MxVideoParam*) SDL_GetPointerProperty( + SDL_GetWindowProperties(reinterpret_cast(m_hWnd)), + ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM, + nullptr + ); +#ifndef MXDIRECTX_FOR_CONFIG + assert(videoParam); +#endif + if (videoParam) { + miniwind3d->RequestMSAA(videoParam->GetMSAASamples()); + miniwind3d->RequestAnisotropic(videoParam->GetAnisotropic()); + } + } + result = lpDD->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL); if (result != DD_OK) { BuildErrorString("SetCooperativeLevel failed: %s\n", EnumerateErrorToString(result)); diff --git a/LEGO1/omni/include/mxaudiomanager.h b/LEGO1/omni/include/mxaudiomanager.h index f962a16d..bab1f553 100644 --- a/LEGO1/omni/include/mxaudiomanager.h +++ b/LEGO1/omni/include/mxaudiomanager.h @@ -2,11 +2,12 @@ #define MXAUDIOMANAGER_H #include "decomp.h" -#include "mxmediamanager.h" +#include "mxpresentationmanager.h" // VTABLE: LEGO1 0x100dc6e0 +// VTABLE: BETA10 0x101c2348 // SIZE 0x30 -class MxAudioManager : public MxMediaManager { +class MxAudioManager : public MxPresentationManager { public: MxAudioManager(); ~MxAudioManager() override; @@ -15,11 +16,13 @@ class MxAudioManager : public MxMediaManager { void Destroy() override; // vtable+18 // FUNCTION: LEGO1 0x10029910 + // FUNCTION: BETA10 0x100d0630 virtual MxS32 GetVolume() { return m_volume; } // vtable+28 virtual void SetVolume(MxS32 p_volume); // vtable+2c // SYNTHETIC: LEGO1 0x100b8d70 + // SYNTHETIC: BETA10 0x10145110 // MxAudioManager::`scalar deleting destructor' private: diff --git a/LEGO1/omni/include/mxautolock.h b/LEGO1/omni/include/mxautolock.h index 8a2b3c35..6a26ba47 100644 --- a/LEGO1/omni/include/mxautolock.h +++ b/LEGO1/omni/include/mxautolock.h @@ -3,15 +3,27 @@ class MxCriticalSection; +#ifdef BETA10 +#define AUTOLOCK(CS) MxAutoLock lock(&CS, __FILE__, __LINE__) +#else #define AUTOLOCK(CS) MxAutoLock lock(&CS) +#endif class MxAutoLock { public: +#ifdef BETA10 + MxAutoLock(MxCriticalSection* p_criticalSection, const char* filename, int line); +#else MxAutoLock(MxCriticalSection* p_criticalSection); +#endif ~MxAutoLock(); private: MxCriticalSection* m_criticalSection; // 0x00 + +#ifdef BETA10 + unsigned long m_currentThreadId; // 0x04 +#endif }; #endif // MXAUTOLOCK_H diff --git a/LEGO1/omni/include/mxcriticalsection.h b/LEGO1/omni/include/mxcriticalsection.h index 9a5c85b6..81767fd9 100644 --- a/LEGO1/omni/include/mxcriticalsection.h +++ b/LEGO1/omni/include/mxcriticalsection.h @@ -11,7 +11,11 @@ class MxCriticalSection { static void SetDoMutex(); +#ifdef BETA10 + void Enter(unsigned long p_threadId, const char* filename, int line); +#else void Enter(); +#endif void Leave(); private: @@ -22,4 +26,11 @@ class MxCriticalSection { SDL_Mutex* m_mutex; }; +#ifdef BETA10 +// TODO: Not quite correct yet, the second argument becomes a relocated value +#define ENTER(criticalSection) criticalSection.Enter(-1, NULL, 0) +#else +#define ENTER(criticalSection) criticalSection.Enter() +#endif + #endif // MXCRITICALSECTION_H diff --git a/LEGO1/omni/include/mxeventmanager.h b/LEGO1/omni/include/mxeventmanager.h index b23a2ad0..f17f886d 100644 --- a/LEGO1/omni/include/mxeventmanager.h +++ b/LEGO1/omni/include/mxeventmanager.h @@ -2,11 +2,11 @@ #define MXEVENTMANAGER_H #include "decomp.h" -#include "mxmediamanager.h" +#include "mxpresentationmanager.h" // VTABLE: LEGO1 0x100dc900 // SIZE 0x2c -class MxEventManager : public MxMediaManager { +class MxEventManager : public MxPresentationManager { public: MxEventManager(); ~MxEventManager() override; diff --git a/LEGO1/omni/include/mxlist.h b/LEGO1/omni/include/mxlist.h index 6d46cb2a..3fe72d0f 100644 --- a/LEGO1/omni/include/mxlist.h +++ b/LEGO1/omni/include/mxlist.h @@ -254,11 +254,11 @@ inline MxBool MxListCursor::Next() template inline MxBool MxListCursor::Next(T& p_obj) { - if (!m_match) { - m_match = m_list->m_first; + if (m_match) { + m_match = m_match->GetNext(); } else { - m_match = m_match->GetNext(); + m_match = m_list->m_first; } if (m_match) { diff --git a/LEGO1/omni/include/mxloopingflcpresenter.h b/LEGO1/omni/include/mxloopingflcpresenter.h index 08232aa4..65361702 100644 --- a/LEGO1/omni/include/mxloopingflcpresenter.h +++ b/LEGO1/omni/include/mxloopingflcpresenter.h @@ -25,11 +25,11 @@ class MxLoopingFlcPresenter : public MxFlcPresenter { return HandlerClassName(); } - void RepeatingTickle() override; // vtable+0x24 - MxResult AddToManager() override; // vtable+0x34 - void Destroy() override; // vtable+0x38 - void NextFrame() override; // vtable+0x64 - virtual void VTable0x88(); // vtable+0x88 + void RepeatingTickle() override; // vtable+0x24 + MxResult AddToManager() override; // vtable+0x34 + void Destroy() override; // vtable+0x38 + void NextFrame() override; // vtable+0x64 + virtual void LoadFrameIfRequired(); // vtable+0x88 // SYNTHETIC: LEGO1 0x100b4390 // MxLoopingFlcPresenter::`scalar deleting destructor' diff --git a/LEGO1/omni/include/mxloopingsmkpresenter.h b/LEGO1/omni/include/mxloopingsmkpresenter.h index 01200170..b1de63fe 100644 --- a/LEGO1/omni/include/mxloopingsmkpresenter.h +++ b/LEGO1/omni/include/mxloopingsmkpresenter.h @@ -25,12 +25,12 @@ class MxLoopingSmkPresenter : public MxSmkPresenter { return HandlerClassName(); } - void RepeatingTickle() override; // vtable+0x24 - MxResult AddToManager() override; // vtable+0x34 - void Destroy() override; // vtable+0x38 - void NextFrame() override; // vtable+0x64 - void VTable0x88() override; // vtable+0x88 - virtual void VTable0x8c(); // vtable+0x8c + void RepeatingTickle() override; // vtable+0x24 + MxResult AddToManager() override; // vtable+0x34 + void Destroy() override; // vtable+0x38 + void NextFrame() override; // vtable+0x64 + void ResetCurrentFrameAtEnd() override; // vtable+0x88 + virtual void LoadFrameIfRequired(); // vtable+0x8c private: void Init(); diff --git a/LEGO1/omni/include/mxomni.h b/LEGO1/omni/include/mxmain.h similarity index 97% rename from LEGO1/omni/include/mxomni.h rename to LEGO1/omni/include/mxmain.h index 0e6bd07c..c9d20482 100644 --- a/LEGO1/omni/include/mxomni.h +++ b/LEGO1/omni/include/mxmain.h @@ -1,5 +1,5 @@ -#ifndef MXOMNI_H -#define MXOMNI_H +#ifndef MXMAIN_H +#define MXMAIN_H #include "lego1_export.h" #include "mxcore.h" @@ -32,6 +32,7 @@ class MxVariableTable; class MxVideoManager; // VTABLE: LEGO1 0x100dc168 +// VTABLE: BETA10 0x101c1c40 // SIZE 0x68 class MxOmni : public MxCore { public: @@ -103,6 +104,7 @@ class MxOmni : public MxCore { MxLong HandleEndAction(MxParam& p_param); // SYNTHETIC: LEGO1 0x100aefd0 + // SYNTHETIC: BETA10 0x10130c90 // MxOmni::`scalar deleting destructor' protected: @@ -128,4 +130,4 @@ class MxOmni : public MxCore { MxBool m_paused; // 0x64 }; -#endif // MXOMNI_H +#endif // MXMAIN_H diff --git a/LEGO1/omni/include/mxomnicreateparam.h b/LEGO1/omni/include/mxomnicreateparam.h index 25c0d9cf..f92b089b 100644 --- a/LEGO1/omni/include/mxomnicreateparam.h +++ b/LEGO1/omni/include/mxomnicreateparam.h @@ -24,8 +24,13 @@ class MxOmniCreateParam : public MxParam { MxOmniCreateFlags& CreateFlags() { return this->m_createFlags; } const MxString& GetMediaPath() const { return m_mediaPath; } - HWND GetWindowHandle() const { return m_windowHandle; } + + // FUNCTION: BETA10 0x10092c50 + const HWND GetWindowHandle() const { return m_windowHandle; } + + // FUNCTION: BETA10 0x10092c80 MxVideoParam& GetVideoParam() { return m_videoParam; } + const MxVideoParam& GetVideoParam() const { return m_videoParam; } // SYNTHETIC: LEGO1 0x100b0a70 diff --git a/LEGO1/omni/include/mxmediamanager.h b/LEGO1/omni/include/mxpresentationmanager.h similarity index 71% rename from LEGO1/omni/include/mxmediamanager.h rename to LEGO1/omni/include/mxpresentationmanager.h index 38f611eb..f0740e6e 100644 --- a/LEGO1/omni/include/mxmediamanager.h +++ b/LEGO1/omni/include/mxpresentationmanager.h @@ -1,5 +1,5 @@ -#ifndef MXMEDIAMANGER_H -#define MXMEDIAMANGER_H +#ifndef MXPRESENTATIONMANAGER_H +#define MXPRESENTATIONMANAGER_H #include "mxcore.h" #include "mxcriticalsection.h" @@ -9,11 +9,12 @@ class MxThread; // VTABLE: LEGO1 0x100dc6b0 +// VTABLE: BETA10 0x101c2318 // SIZE 0x2c -class MxMediaManager : public MxCore { +class MxPresentationManager : public MxCore { public: - MxMediaManager(); - ~MxMediaManager() override; + MxPresentationManager(); + ~MxPresentationManager() override; MxResult Tickle() override; // vtable+08 virtual MxResult Create(); // vtable+14 @@ -25,7 +26,8 @@ class MxMediaManager : public MxCore { MxResult Init(); // SYNTHETIC: LEGO1 0x100b8540 - // MxMediaManager::`scalar deleting destructor' + // SYNTHETIC: BETA10 0x10144db0 + // MxPresentationManager::`scalar deleting destructor' protected: MxPresenterList* m_presenters; // 0x08 @@ -33,4 +35,4 @@ class MxMediaManager : public MxCore { MxCriticalSection m_criticalSection; // 0x10 }; -#endif // MXMEDIAMANGER_H +#endif // MXPRESENTATIONMANAGER_H diff --git a/LEGO1/omni/include/mxpresenterlist.h b/LEGO1/omni/include/mxpresenterlist.h index 0e8bd316..7d3000cc 100644 --- a/LEGO1/omni/include/mxpresenterlist.h +++ b/LEGO1/omni/include/mxpresenterlist.h @@ -5,12 +5,15 @@ #include "mxpresenter.h" // VTABLE: LEGO1 0x100d62f0 +// VTABLE: BETA10 0x101bf070 // class MxPtrList // VTABLE: LEGO1 0x100d6308 +// VTABLE: BETA10 0x101bf050 // SIZE 0x18 class MxPresenterList : public MxPtrList { public: + // FUNCTION: BETA10 0x100dc900 MxPresenterList(MxBool p_ownership = FALSE) : MxPtrList(p_ownership) {} // FUNCTION: LEGO1 0x1001cd00 @@ -35,6 +38,13 @@ class MxPresenterListCursor : public MxPtrListCursor { public: // FUNCTION: BETA10 0x1007d130 MxPresenterListCursor(MxPresenterList* p_list) : MxPtrListCursor(p_list) {} + + // SYNTHETIC: LEGO1 0x1001eed0 + // MxPresenterListCursor::`scalar deleting destructor' + + // SYNTHETIC: LEGO1 0x1001f0c0 + // SYNTHETIC: BETA10 0x1007d510 + // MxPresenterListCursor::~MxPresenterListCursor }; // VTABLE: LEGO1 0x100d6350 @@ -58,7 +68,11 @@ class MxPresenterListCursor : public MxPtrListCursor { // TEMPLATE: LEGO1 0x1001ce20 // MxList::~MxList +// TEMPLATE: BETA10 0x100dc9f0 +// MxPtrList::MxPtrList + // TEMPLATE: LEGO1 0x1001cf20 +// TEMPLATE: BETA10 0x100dce70 // MxPtrList::~MxPtrList // SYNTHETIC: LEGO1 0x1001cf70 @@ -73,10 +87,8 @@ class MxPresenterListCursor : public MxPtrListCursor { // SYNTHETIC: LEGO1 0x1001d100 // MxPresenterList::~MxPresenterList -// SYNTHETIC: LEGO1 0x1001eed0 -// MxPresenterListCursor::`scalar deleting destructor' - // TEMPLATE: LEGO1 0x1001ef40 +// TEMPLATE: BETA10 0x1007d370 // MxPtrListCursor::~MxPtrListCursor // SYNTHETIC: LEGO1 0x1001ef90 @@ -86,11 +98,9 @@ class MxPresenterListCursor : public MxPtrListCursor { // MxPtrListCursor::`scalar deleting destructor' // TEMPLATE: LEGO1 0x1001f070 +// TEMPLATE: BETA10 0x1007d490 // MxListCursor::~MxListCursor -// FUNCTION: LEGO1 0x1001f0c0 -// MxPresenterListCursor::~MxPresenterListCursor - // TEMPLATE: LEGO1 0x10020760 // MxListCursor::MxListCursor @@ -106,6 +116,18 @@ class MxPresenterListCursor : public MxPtrListCursor { // TEMPLATE: BETA10 0x1007d270 // MxListCursor::MxListCursor +// TEMPLATE: BETA10 0x1007dc60 +// MxListCursor::Next + +// TEMPLATE: BETA10 0x100d8f20 +// MxListCursor::Reset + +// TEMPLATE: BETA10 0x1007e070 +// MxListEntry::GetNext + +// TEMPLATE: BETA10 0x1007e0a0 +// MxListEntry::GetValue + // TEMPLATE: BETA10 0x100d9420 // ?Prev@?$MxListCursor@PAVMxPresenter@@@@QAEEAAPAVMxPresenter@@@Z diff --git a/LEGO1/omni/include/mxsemaphore.h b/LEGO1/omni/include/mxsemaphore.h index 1d43009a..fd8b60b0 100644 --- a/LEGO1/omni/include/mxsemaphore.h +++ b/LEGO1/omni/include/mxsemaphore.h @@ -6,17 +6,20 @@ #include // VTABLE: LEGO1 0x100dccf0 +// VTABLE: BETA10 0x101c28ac // SIZE 0x08 class MxSemaphore { public: MxSemaphore(); // FUNCTION: LEGO1 0x100c87e0 + // FUNCTION: BETA10 0x101592a9 ~MxSemaphore() { SDL_DestroySemaphore(m_semaphore); } virtual MxResult Init(MxU32 p_initialCount, MxU32 p_maxCount); - void Wait(); + void Acquire(); + void TryAcquire(); void Release(); private: diff --git a/LEGO1/omni/include/mxsmkpresenter.h b/LEGO1/omni/include/mxsmkpresenter.h index 53f7831f..7becc7cc 100644 --- a/LEGO1/omni/include/mxsmkpresenter.h +++ b/LEGO1/omni/include/mxsmkpresenter.h @@ -38,7 +38,7 @@ class MxSmkPresenter : public MxVideoPresenter { void CreateBitmap() override; // vtable+0x60 void LoadFrame(MxStreamChunk* p_chunk) override; // vtable+0x68 void RealizePalette() override; // vtable+0x70 - virtual void VTable0x88(); // vtable+0x88 + virtual void ResetCurrentFrameAtEnd(); // vtable+0x88 // SYNTHETIC: LEGO1 0x100b3850 // MxSmkPresenter::`scalar deleting destructor' diff --git a/LEGO1/omni/include/mxsoundmanager.h b/LEGO1/omni/include/mxsoundmanager.h index 062d3839..569a7ff1 100644 --- a/LEGO1/omni/include/mxsoundmanager.h +++ b/LEGO1/omni/include/mxsoundmanager.h @@ -26,7 +26,11 @@ class MxSoundManager : public MxAudioManager { float GetAttenuation(MxU32 p_volume); - MxPresenter* FUN_100aebd0(const MxAtomId& p_atomId, MxU32 p_objectId); + MxPresenter* FindPresenter(const MxAtomId& p_atomId, MxU32 p_objectId); + + // SYNTHETIC: LEGO1 0x100ae7b0 + // SYNTHETIC: BETA10 0x10133460 + // MxSoundManager::`scalar deleting destructor' protected: void Init(); @@ -49,7 +53,4 @@ class MxSoundManager : public MxAudioManager { undefined m_unk0x38[4]; }; -// SYNTHETIC: LEGO1 0x100ae7b0 -// MxSoundManager::`scalar deleting destructor' - #endif // MXSOUNDMANAGER_H diff --git a/LEGO1/omni/include/mxthread.h b/LEGO1/omni/include/mxthread.h index 8afa4454..0772dc65 100644 --- a/LEGO1/omni/include/mxthread.h +++ b/LEGO1/omni/include/mxthread.h @@ -10,6 +10,7 @@ class MxCore; // VTABLE: LEGO1 0x100dc860 +// VTABLE: BETA10 0x101c23e8 // SIZE 0x1c class MxThread { public: @@ -21,9 +22,16 @@ class MxThread { void Terminate(); void Sleep(MxS32 p_milliseconds); + void ResumeThread(); + void SuspendThread(); + bool TerminateThread(MxU32 p_exitCode); + MxS32 GetThreadPriority(MxU16& p_priority); + bool SetThreadPriority(MxU16 p_priority); + MxBool IsRunning() { return m_running; } // SYNTHETIC: LEGO1 0x100bf580 + // SYNTHETIC: BETA10 0x10147880 // MxThread::`scalar deleting destructor' protected: diff --git a/LEGO1/omni/include/mxutilities.h b/LEGO1/omni/include/mxutilities.h index 33754f3c..7ea9fed5 100644 --- a/LEGO1/omni/include/mxutilities.h +++ b/LEGO1/omni/include/mxutilities.h @@ -10,7 +10,7 @@ struct LegoSdlEvents { Uint32 m_windowsMessage; Uint32 m_presenterProgress; - Uint32 m_hitActor; + Uint32 m_gameEvent; }; LEGO1_EXPORT extern LegoSdlEvents g_legoSdlEvents; diff --git a/LEGO1/omni/include/mxvariable.h b/LEGO1/omni/include/mxvariable.h index 8949833f..9eda281f 100644 --- a/LEGO1/omni/include/mxvariable.h +++ b/LEGO1/omni/include/mxvariable.h @@ -9,6 +9,7 @@ // SIZE 0x24 class MxVariable { public: + // FUNCTION: BETA10 0x1007b750 MxVariable() {} // FUNCTION: BETA10 0x1012a840 @@ -41,12 +42,16 @@ class MxVariable { // FUNCTION: BETA10 0x1012a7f0 const MxString* GetKey() const { return &m_key; } + // SYNTHETIC: BETA10 0x1007b8c0 + // MxVariable::`scalar deleting destructor' + protected: MxString m_key; // 0x04 MxString m_value; // 0x14 }; // SYNTHETIC: LEGO1 0x1003bf40 +// SYNTHETIC: BETA10 0x1007b910 // MxVariable::~MxVariable #endif // MXVARIABLE_H diff --git a/LEGO1/omni/include/mxvideomanager.h b/LEGO1/omni/include/mxvideomanager.h index 04855a10..08632f74 100644 --- a/LEGO1/omni/include/mxvideomanager.h +++ b/LEGO1/omni/include/mxvideomanager.h @@ -1,7 +1,7 @@ #ifndef MXVIDEOMANAGER_H #define MXVIDEOMANAGER_H -#include "mxmediamanager.h" +#include "mxpresentationmanager.h" #include "mxvideoparam.h" #ifdef MINIWIN @@ -15,8 +15,9 @@ class MxRect32; class MxRegion; // VTABLE: LEGO1 0x100dc810 +// VTABLE: BETA10 0x101c1bf8 // SIZE 0x64 -class MxVideoManager : public MxMediaManager { +class MxVideoManager : public MxPresentationManager { public: MxVideoManager(); ~MxVideoManager() override; @@ -52,6 +53,7 @@ class MxVideoManager : public MxMediaManager { MxRegion* GetRegion() { return this->m_region; } // SYNTHETIC: LEGO1 0x100be280 + // SYNTHETIC: BETA10 0x1012de00 // MxVideoManager::`scalar deleting destructor' protected: diff --git a/LEGO1/omni/include/mxvideoparam.h b/LEGO1/omni/include/mxvideoparam.h index ccc073ab..cd425ba9 100644 --- a/LEGO1/omni/include/mxvideoparam.h +++ b/LEGO1/omni/include/mxvideoparam.h @@ -15,6 +15,8 @@ class MxPalette; +#define ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM "ISLE.window.create.videoParam" + // SIZE 0x24 class MxVideoParam { public: @@ -51,6 +53,12 @@ class MxVideoParam { // FUNCTION: BETA10 0x10141fe0 void SetBackBuffers(MxU32 p_backBuffers) { m_backBuffers = p_backBuffers; } + void SetMSAASamples(MxU32 p_msaaSamples) { m_msaaSamples = p_msaaSamples; } + MxU32 GetMSAASamples() { return m_msaaSamples; } + + void SetAnisotropic(MxFloat p_anisotropic) { m_anisotropic = p_anisotropic; } + MxFloat GetAnisotropic() { return m_anisotropic; } + private: MxRect32 m_rect; // 0x00 MxPalette* m_palette; // 0x10 @@ -58,6 +66,8 @@ class MxVideoParam { MxVideoParamFlags m_flags; // 0x18 int m_unk0x1c; // 0x1c char* m_deviceId; // 0x20 + MxU32 m_msaaSamples; + MxFloat m_anisotropic; }; #endif // MXVIDEOPARAM_H diff --git a/LEGO1/omni/include/mxvideoparamflags.h b/LEGO1/omni/include/mxvideoparamflags.h index 4fef2145..6158c4d7 100644 --- a/LEGO1/omni/include/mxvideoparamflags.h +++ b/LEGO1/omni/include/mxvideoparamflags.h @@ -24,7 +24,7 @@ class MxVideoParamFlags { void SetBackBuffers(MxBool p_e) { m_flags1.m_bit2 = p_e; } // FUNCTION: BETA10 0x100d9250 - void SetF1bit3(MxBool p_e) { m_flags1.m_bit3 = p_e; } + void SetDoubleScaling(MxBool p_e) { m_flags1.m_bit3 = p_e; } // inlined in ISLE void Set16Bit(MxBool p_e) { m_flags1.m_bit5 = p_e; } @@ -39,7 +39,7 @@ class MxVideoParamFlags { void SetLacksLightSupport(MxBool p_e) { m_flags2.m_bit0 = p_e; } // inlined in ISLE - void SetF2bit1(MxBool p_e) { m_flags2.m_bit1 = p_e; } + void SetEnabled(MxBool p_e) { m_flags2.m_bit1 = p_e; } // FUNCTION: BETA10 0x1009e770 MxBool GetFullScreen() { return m_flags1.m_bit0; } @@ -51,7 +51,7 @@ class MxVideoParamFlags { MxBool GetBackBuffers() { return m_flags1.m_bit2; } // FUNCTION: BETA10 0x10142010 - MxBool GetF1bit3() { return m_flags1.m_bit3; } + MxBool GetDoubleScaling() { return m_flags1.m_bit3; } // FUNCTION: BETA10 0x100d8150 MxBool Get16Bit() { return m_flags1.m_bit5; } @@ -63,7 +63,7 @@ class MxVideoParamFlags { MxBool GetLacksLightSupport() { return m_flags2.m_bit0; } // FUNCTION: BETA10 0x10142050 - MxBool GetF2bit1() { return m_flags2.m_bit1; } + MxBool GetEnabled() { return m_flags2.m_bit1; } private: FlagBitfield m_flags1; diff --git a/LEGO1/omni/include/mxvideopresenter.h b/LEGO1/omni/include/mxvideopresenter.h index b380a3a7..45163de0 100644 --- a/LEGO1/omni/include/mxvideopresenter.h +++ b/LEGO1/omni/include/mxvideopresenter.h @@ -46,10 +46,10 @@ class MxVideoPresenter : public MxMediaPresenter { void Destroy() override { Destroy(FALSE); } // vtable+0x38 // FUNCTION: LEGO1 0x1000c7b0 - virtual LPDIRECTDRAWSURFACE VTable0x78() { return m_unk0x58; } // vtable+0x78 + virtual LPDIRECTDRAWSURFACE GetSurface() { return m_surface; } // vtable+0x78 // FUNCTION: LEGO1 0x1000c7c0 - virtual MxBool VTable0x7c() { return m_frameBitmap != NULL || m_alpha != NULL; } // vtable+0x7c + virtual MxBool HasFrameBitmapOrAlpha() { return m_frameBitmap != NULL || m_alpha != NULL; } // vtable+0x7c // FUNCTION: LEGO1 0x1000c7e0 virtual MxS32 GetWidth() { return m_alpha ? m_alpha->GetWidth() : m_frameBitmap->GetBmiWidth(); } // vtable+0x80 @@ -119,17 +119,17 @@ class MxVideoPresenter : public MxMediaPresenter { // FUNCTION: BETA10 0x1002c2e0 MxU8* GetBitmapStart(MxS32 p_left, MxS32 p_top) { return m_frameBitmap->GetStart(p_left, p_top); } - void SetBit0(BOOL p_e) { m_flags.m_bit0 = p_e; } - void SetBit1(BOOL p_e) { m_flags.m_bit1 = p_e; } - void SetBit2(BOOL p_e) { m_flags.m_bit2 = p_e; } - void SetBit3(BOOL p_e) { m_flags.m_bit3 = p_e; } - void SetBit4(BOOL p_e) { m_flags.m_bit4 = p_e; } + void SetLoadedFirstFrame(BOOL p_loadedFirstFrame) { m_flags.m_bit0 = p_loadedFirstFrame; } + void SetUseSurface(BOOL p_useSurface) { m_flags.m_bit1 = p_useSurface; } + void SetUseVideoMemory(BOOL p_useVideoMemory) { m_flags.m_bit2 = p_useVideoMemory; } + void SetDoNotWriteToSurface(BOOL p_doNotWriteToSurface) { m_flags.m_bit3 = p_doNotWriteToSurface; } + void SetBitmapIsMap(BOOL p_bitmapIsMap) { m_flags.m_bit4 = p_bitmapIsMap; } - BYTE GetBit0() { return m_flags.m_bit0; } - BYTE GetBit1() { return m_flags.m_bit1; } - BYTE GetBit2() { return m_flags.m_bit2; } - BYTE GetBit3() { return m_flags.m_bit3; } - BYTE GetBit4() { return m_flags.m_bit4; } + BYTE LoadedFirstFrame() { return m_flags.m_bit0; } + BYTE UseSurface() { return m_flags.m_bit1; } + BYTE UseVideoMemory() { return m_flags.m_bit2; } + BYTE DoNotWriteToSurface() { return m_flags.m_bit3; } + BYTE BitmapIsMap() { return m_flags.m_bit4; } // SYNTHETIC: LEGO1 0x1000c910 // MxVideoPresenter::`scalar deleting destructor' @@ -142,10 +142,10 @@ class MxVideoPresenter : public MxMediaPresenter { MxBitmap* m_frameBitmap; // 0x50 AlphaMask* m_alpha; // 0x54 - LPDIRECTDRAWSURFACE m_unk0x58; // 0x58 - MxS16 m_unk0x5c; // 0x5c + LPDIRECTDRAWSURFACE m_surface; // 0x58 + MxS16 m_frameLoadTickleCount; // 0x5c FlagBitfield m_flags; // 0x5e - MxLong m_unk0x60; // 0x60 + MxLong m_frozenTime; // 0x60 }; #endif // MXVIDEOPRESENTER_H diff --git a/LEGO1/omni/src/audio/mxaudiomanager.cpp b/LEGO1/omni/src/audio/mxaudiomanager.cpp index 81b8922e..3cef829a 100644 --- a/LEGO1/omni/src/audio/mxaudiomanager.cpp +++ b/LEGO1/omni/src/audio/mxaudiomanager.cpp @@ -3,47 +3,84 @@ DECOMP_SIZE_ASSERT(MxAudioManager, 0x30); // GLOBAL: LEGO1 0x10102108 +// GLOBAL: BETA10 0x10203a60 MxS32 MxAudioManager::g_count = 0; // FUNCTION: LEGO1 0x100b8d00 +// FUNCTION: BETA10 0x10144e90 MxAudioManager::MxAudioManager() { Init(); } // FUNCTION: LEGO1 0x100b8d90 +// STUB: BETA10 0x10144f07 MxAudioManager::~MxAudioManager() { Destroy(TRUE); } // FUNCTION: LEGO1 0x100b8df0 +// FUNCTION: BETA10 0x10144f79 void MxAudioManager::Init() { m_volume = 100; } // FUNCTION: LEGO1 0x100b8e00 +// FUNCTION: BETA10 0x10144f9c void MxAudioManager::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); g_count--; Init(); m_criticalSection.Leave(); if (!p_fromDestructor) { - MxMediaManager::Destroy(); + MxPresentationManager::Destroy(); } } +#ifdef BETA10 +// FUNCTION: BETA10 0x10144ffe +MxResult MxAudioManager::Create() +{ + MxResult result = FAILURE; + MxBool success = FALSE; + + if (MxPresentationManager::Create() != SUCCESS) { + goto exit; + } + + ENTER(m_criticalSection); + success = TRUE; + + if (!g_count++) { + // This is correct. It was likely refactored later. + } + +exit: + result = SUCCESS; + + if (result) { + Destroy(); + } + + if (success) { + m_criticalSection.Leave(); + } + + return result; +} +#else // FUNCTION: LEGO1 0x100b8e40 MxResult MxAudioManager::Create() { MxResult result = FAILURE; MxBool success = FALSE; - if (MxMediaManager::Create() == SUCCESS) { - m_criticalSection.Enter(); + if (MxPresentationManager::Create() == SUCCESS) { + ENTER(m_criticalSection); success = TRUE; result = SUCCESS; g_count++; @@ -59,17 +96,20 @@ MxResult MxAudioManager::Create() return result; } +#endif // FUNCTION: LEGO1 0x100b8e90 +// FUNCTION: BETA10 0x101450a7 void MxAudioManager::Destroy() { Destroy(FALSE); } // FUNCTION: LEGO1 0x100b8ea0 +// FUNCTION: BETA10 0x101450c7 void MxAudioManager::SetVolume(MxS32 p_volume) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); m_volume = p_volume; m_criticalSection.Leave(); } diff --git a/LEGO1/omni/src/audio/mxsoundmanager.cpp b/LEGO1/omni/src/audio/mxsoundmanager.cpp index f865ebf0..39091e8f 100644 --- a/LEGO1/omni/src/audio/mxsoundmanager.cpp +++ b/LEGO1/omni/src/audio/mxsoundmanager.cpp @@ -2,8 +2,8 @@ #include "mxautolock.h" #include "mxdsaction.h" +#include "mxmain.h" #include "mxmisc.h" -#include "mxomni.h" #include "mxpresenter.h" #include "mxticklemanager.h" #include "mxticklethread.h" @@ -25,18 +25,21 @@ MxS32 g_volumeAttenuation[100] = {-6643, -5643, -5058, -4643, -4321, -4058, -383 -43, -29, -14, 0}; // FUNCTION: LEGO1 0x100ae740 +// FUNCTION: BETA10 0x10132c70 MxSoundManager::MxSoundManager() { Init(); } // FUNCTION: LEGO1 0x100ae7d0 +// FUNCTION: BETA10 0x10132ce7 MxSoundManager::~MxSoundManager() { Destroy(TRUE); } // FUNCTION: LEGO1 0x100ae830 +// FUNCTION: BETA10 0x10132d59 void MxSoundManager::Init() { SDL_zero(m_engine); @@ -44,6 +47,7 @@ void MxSoundManager::Init() } // FUNCTION: LEGO1 0x100ae840 +// FUNCTION: BETA10 0x10132d89 void MxSoundManager::Destroy(MxBool p_fromDestructor) { if (m_thread) { @@ -54,7 +58,7 @@ void MxSoundManager::Destroy(MxBool p_fromDestructor) TickleManager()->UnregisterClient(this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_stream) { SDL_DestroyAudioStream(m_stream); @@ -82,7 +86,7 @@ MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) goto done; } - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; engineConfig = ma_engine_config_init(); @@ -157,17 +161,19 @@ void MxSoundManager::AudioStreamCallback( } // FUNCTION: LEGO1 0x100aeab0 +// FUNCTION: BETA10 0x101331e3 void MxSoundManager::Destroy() { Destroy(FALSE); } // FUNCTION: LEGO1 0x100aeac0 +// FUNCTION: BETA10 0x10133203 void MxSoundManager::SetVolume(MxS32 p_volume) { MxAudioManager::SetVolume(p_volume); - m_criticalSection.Enter(); + ENTER(m_criticalSection); MxPresenter* presenter; MxPresenterListCursor cursor(m_presenters); @@ -180,7 +186,8 @@ void MxSoundManager::SetVolume(MxS32 p_volume) } // FUNCTION: LEGO1 0x100aebd0 -MxPresenter* MxSoundManager::FUN_100aebd0(const MxAtomId& p_atomId, MxU32 p_objectId) +// FUNCTION: BETA10 0x101332cf +MxPresenter* MxSoundManager::FindPresenter(const MxAtomId& p_atomId, MxU32 p_objectId) { AUTOLOCK(m_criticalSection); @@ -188,8 +195,7 @@ MxPresenter* MxSoundManager::FUN_100aebd0(const MxAtomId& p_atomId, MxU32 p_obje MxPresenterListCursor cursor(m_presenters); while (cursor.Next(presenter)) { - if (presenter->GetAction()->GetAtomId().GetInternal() == p_atomId.GetInternal() && - presenter->GetAction()->GetObjectId() == p_objectId) { + if (presenter->GetAction()->GetAtomId() == p_atomId && presenter->GetAction()->GetObjectId() == p_objectId) { return presenter; } } diff --git a/LEGO1/omni/src/audio/mxsoundpresenter.cpp b/LEGO1/omni/src/audio/mxsoundpresenter.cpp index 9d784532..3fa2cfaa 100644 --- a/LEGO1/omni/src/audio/mxsoundpresenter.cpp +++ b/LEGO1/omni/src/audio/mxsoundpresenter.cpp @@ -13,7 +13,7 @@ void MxSoundPresenter::Destroy(MxBool p_fromDestructor) MSoundManager()->UnregisterPresenter(*this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); MxMediaPresenter::Init(); m_criticalSection.Leave(); diff --git a/LEGO1/omni/src/audio/mxwavepresenter.cpp b/LEGO1/omni/src/audio/mxwavepresenter.cpp index 600d9b37..83e1f7c7 100644 --- a/LEGO1/omni/src/audio/mxwavepresenter.cpp +++ b/LEGO1/omni/src/audio/mxwavepresenter.cpp @@ -5,8 +5,8 @@ #include "mxautolock.h" #include "mxdssound.h" #include "mxdssubscriber.h" +#include "mxmain.h" #include "mxmisc.h" -#include "mxomni.h" #include "mxsoundmanager.h" #include "mxutilities.h" @@ -289,7 +289,7 @@ void MxWavePresenter::EndAction() // FUNCTION: LEGO1 0x100b2300 void MxWavePresenter::SetVolume(MxS32 p_volume) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); m_volume = p_volume; if (m_sound) { diff --git a/LEGO1/omni/src/common/mxatom.cpp b/LEGO1/omni/src/common/mxatom.cpp index e242ebb0..942346ec 100644 --- a/LEGO1/omni/src/common/mxatom.cpp +++ b/LEGO1/omni/src/common/mxatom.cpp @@ -1,8 +1,8 @@ #include "mxatom.h" #include "decomp.h" +#include "mxmain.h" #include "mxmisc.h" -#include "mxomni.h" #include diff --git a/LEGO1/omni/src/common/mxcompositepresenter.cpp b/LEGO1/omni/src/common/mxcompositepresenter.cpp index 4e83d86c..b3d56875 100644 --- a/LEGO1/omni/src/common/mxcompositepresenter.cpp +++ b/LEGO1/omni/src/common/mxcompositepresenter.cpp @@ -25,7 +25,7 @@ MxCompositePresenter::~MxCompositePresenter() } // FUNCTION: LEGO1 0x100b6410 -// FUNCTION: BETA10 0x100e9d37 +// FUNCTION: BETA10 0x10137344 MxResult MxCompositePresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) { AUTOLOCK(m_criticalSection); diff --git a/LEGO1/omni/src/common/mxmediapresenter.cpp b/LEGO1/omni/src/common/mxmediapresenter.cpp index c8b9abcd..11621f71 100644 --- a/LEGO1/omni/src/common/mxmediapresenter.cpp +++ b/LEGO1/omni/src/common/mxmediapresenter.cpp @@ -131,6 +131,7 @@ MxResult MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAct } // FUNCTION: LEGO1 0x100b5bc0 +// STUB: BETA10 0x1013623c void MxMediaPresenter::EndAction() { AUTOLOCK(m_criticalSection); diff --git a/LEGO1/omni/src/common/mxmisc.cpp b/LEGO1/omni/src/common/mxmisc.cpp index 98e21f89..a6f3f7e0 100644 --- a/LEGO1/omni/src/common/mxmisc.cpp +++ b/LEGO1/omni/src/common/mxmisc.cpp @@ -1,6 +1,6 @@ #include "mxmisc.h" -#include "mxomni.h" +#include "mxmain.h" #include diff --git a/LEGO1/omni/src/common/mxmediamanager.cpp b/LEGO1/omni/src/common/mxpresentationmanager.cpp similarity index 62% rename from LEGO1/omni/src/common/mxmediamanager.cpp rename to LEGO1/omni/src/common/mxpresentationmanager.cpp index cc1611ae..e4d96fb3 100644 --- a/LEGO1/omni/src/common/mxmediamanager.cpp +++ b/LEGO1/omni/src/common/mxpresentationmanager.cpp @@ -1,29 +1,32 @@ -#include "mxmediamanager.h" +#include "mxpresentationmanager.h" #include "decomp.h" #include "mxautolock.h" -#include "mxomni.h" +#include "mxmain.h" #include "mxpresenter.h" #include "mxticklemanager.h" -DECOMP_SIZE_ASSERT(MxMediaManager, 0x2c); +DECOMP_SIZE_ASSERT(MxPresentationManager, 0x2c); DECOMP_SIZE_ASSERT(MxPresenterList, 0x18); DECOMP_SIZE_ASSERT(MxPresenterListCursor, 0x10); // FUNCTION: LEGO1 0x100b84c0 -MxMediaManager::MxMediaManager() +// FUNCTION: BETA10 0x10144680 +MxPresentationManager::MxPresentationManager() { Init(); } // FUNCTION: LEGO1 0x100b8560 -MxMediaManager::~MxMediaManager() +// FUNCTION: BETA10 0x10144712 +MxPresentationManager::~MxPresentationManager() { Destroy(); } // FUNCTION: LEGO1 0x100b85d0 -MxResult MxMediaManager::Init() +// FUNCTION: BETA10 0x1014479b +MxResult MxPresentationManager::Init() { this->m_presenters = NULL; this->m_thread = NULL; @@ -31,8 +34,10 @@ MxResult MxMediaManager::Init() } // FUNCTION: LEGO1 0x100b85e0 -MxResult MxMediaManager::Create() +// FUNCTION: BETA10 0x101447c5 +MxResult MxPresentationManager::Create() { + // This validates the name of the source code file (and hence also the name of the class) AUTOLOCK(m_criticalSection); this->m_presenters = new MxPresenterList; @@ -46,7 +51,8 @@ MxResult MxMediaManager::Create() } // FUNCTION: LEGO1 0x100b8710 -void MxMediaManager::Destroy() +// FUNCTION: BETA10 0x101448e4 +void MxPresentationManager::Destroy() { AUTOLOCK(m_criticalSection); @@ -58,7 +64,8 @@ void MxMediaManager::Destroy() } // FUNCTION: LEGO1 0x100b8790 -MxResult MxMediaManager::Tickle() +// FUNCTION: BETA10 0x10144993 +MxResult MxPresentationManager::Tickle() { AUTOLOCK(m_criticalSection); MxPresenter* presenter; @@ -78,7 +85,8 @@ MxResult MxMediaManager::Tickle() } // FUNCTION: LEGO1 0x100b88c0 -void MxMediaManager::RegisterPresenter(MxPresenter& p_presenter) +// FUNCTION: BETA10 0x10144a8b +void MxPresentationManager::RegisterPresenter(MxPresenter& p_presenter) { AUTOLOCK(m_criticalSection); @@ -86,7 +94,8 @@ void MxMediaManager::RegisterPresenter(MxPresenter& p_presenter) } // FUNCTION: LEGO1 0x100b8980 -void MxMediaManager::UnregisterPresenter(MxPresenter& p_presenter) +// FUNCTION: BETA10 0x10144b0c +void MxPresentationManager::UnregisterPresenter(MxPresenter& p_presenter) { AUTOLOCK(m_criticalSection); MxPresenterListCursor cursor(this->m_presenters); @@ -97,7 +106,8 @@ void MxMediaManager::UnregisterPresenter(MxPresenter& p_presenter) } // FUNCTION: LEGO1 0x100b8ac0 -void MxMediaManager::StopPresenters() +// FUNCTION: BETA10 0x10144bc3 +void MxPresentationManager::StopPresenters() { AUTOLOCK(m_criticalSection); MxPresenter* presenter; diff --git a/LEGO1/omni/src/common/mxpresenter.cpp b/LEGO1/omni/src/common/mxpresenter.cpp index 0b2648bb..572dde35 100644 --- a/LEGO1/omni/src/common/mxpresenter.cpp +++ b/LEGO1/omni/src/common/mxpresenter.cpp @@ -12,10 +12,10 @@ #include "mxflcpresenter.h" #include "mxloopingflcpresenter.h" #include "mxloopingsmkpresenter.h" +#include "mxmain.h" #include "mxmisc.h" #include "mxnotificationmanager.h" #include "mxobjectfactory.h" -#include "mxomni.h" #include "mxparam.h" #include "mxsmkpresenter.h" #include "mxstillpresenter.h" diff --git a/LEGO1/omni/src/common/mxstring.cpp b/LEGO1/omni/src/common/mxstring.cpp index e8167a0c..fc63d70b 100644 --- a/LEGO1/omni/src/common/mxstring.cpp +++ b/LEGO1/omni/src/common/mxstring.cpp @@ -1,7 +1,7 @@ #include "mxstring.h" #include "decomp.h" -#include "mxomni.h" +#include "mxmain.h" #include #include diff --git a/LEGO1/omni/src/event/mxeventmanager.cpp b/LEGO1/omni/src/event/mxeventmanager.cpp index 29b8aba0..91a22abb 100644 --- a/LEGO1/omni/src/event/mxeventmanager.cpp +++ b/LEGO1/omni/src/event/mxeventmanager.cpp @@ -35,7 +35,7 @@ void MxEventManager::Destroy(MxBool p_fromDestructor) } if (!p_fromDestructor) { - MxMediaManager::Destroy(); + MxPresentationManager::Destroy(); } } @@ -45,10 +45,10 @@ MxResult MxEventManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) MxResult status = FAILURE; MxBool locked = FALSE; - MxResult result = MxMediaManager::Create(); + MxResult result = MxPresentationManager::Create(); if (result == SUCCESS) { if (p_createThread) { - this->m_criticalSection.Enter(); + ENTER(this->m_criticalSection); locked = TRUE; this->m_thread = new MxTickleThread(this, p_frequencyMS); diff --git a/LEGO1/omni/src/event/mxeventpresenter.cpp b/LEGO1/omni/src/event/mxeventpresenter.cpp index f819b68c..8134465e 100644 --- a/LEGO1/omni/src/event/mxeventpresenter.cpp +++ b/LEGO1/omni/src/event/mxeventpresenter.cpp @@ -50,7 +50,7 @@ void MxEventPresenter::Destroy() EventManager()->UnregisterPresenter(*this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_data) { delete[] m_data; diff --git a/LEGO1/omni/src/main/mxomni.cpp b/LEGO1/omni/src/main/mxmain.cpp similarity index 96% rename from LEGO1/omni/src/main/mxomni.cpp rename to LEGO1/omni/src/main/mxmain.cpp index b6081b16..dc146927 100644 --- a/LEGO1/omni/src/main/mxomni.cpp +++ b/LEGO1/omni/src/main/mxmain.cpp @@ -1,4 +1,4 @@ -#include "mxomni.h" +#include "mxmain.h" #include "mxactionnotificationparam.h" #include "mxatom.h" @@ -42,23 +42,27 @@ MxOmni::MxOmni() } // FUNCTION: LEGO1 0x100aefb0 +// FUNCTION: BETA10 0x10130c50 MxEntity* MxOmni::AddToWorld(const char*, MxS32, MxPresenter*) { return NULL; } // FUNCTION: LEGO1 0x100aefc0 +// FUNCTION: BETA10 0x10130c70 void MxOmni::NotifyCurrentEntity(const MxNotificationParam& p_param) { } // FUNCTION: LEGO1 0x100aeff0 +// STUB: BETA10 0x1012f2b7 MxOmni::~MxOmni() { Destroy(); } // FUNCTION: LEGO1 0x100af080 +// FUNCTION: BETA10 0x1012f359 void MxOmni::Init() { m_windowHandle = NULL; @@ -166,7 +170,7 @@ MxResult MxOmni::Create(MxOmniCreateParam& p_param) Uint32 event = SDL_RegisterEvents(3); g_legoSdlEvents.m_windowsMessage = event + 0; g_legoSdlEvents.m_presenterProgress = event + 1; - g_legoSdlEvents.m_hitActor = event + 2; + g_legoSdlEvents.m_gameEvent = event + 2; } result = SUCCESS; @@ -224,6 +228,7 @@ void MxOmni::Destroy() } // FUNCTION: LEGO1 0x100b0090 +// STUB: BETA10 0x101303ce MxResult MxOmni::Start(MxDSAction* p_dsAction) { MxResult result = FAILURE; @@ -235,6 +240,7 @@ MxResult MxOmni::Start(MxDSAction* p_dsAction) } // FUNCTION: LEGO1 0x100b00c0 +// FUNCTION: BETA10 0x101304aa void MxOmni::DeleteObject(MxDSAction& p_dsAction) { if (m_streamer != NULL) { @@ -243,6 +249,7 @@ void MxOmni::DeleteObject(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x100b00e0 +// FUNCTION: BETA10 0x101304de MxResult MxOmni::CreatePresenter(MxStreamController* p_controller, MxDSAction& p_action) { MxResult result = FAILURE; @@ -323,6 +330,7 @@ MxBool MxOmni::ActionSourceEquals(MxDSAction* p_action, const char* p_name) } // FUNCTION: LEGO1 0x100b07f0 +// STUB: BETA10 0x1013082b MxLong MxOmni::Notify(MxParam& p_param) { AUTOLOCK(m_criticalSection); @@ -399,6 +407,7 @@ void MxOmni::SetSound3D(MxBool p_use3dSound) } // FUNCTION: LEGO1 0x100b09a0 +// FUNCTION: BETA10 0x101309f5 MxBool MxOmni::DoesEntityExist(MxDSAction& p_dsAction) { if (m_streamer->FUN_100b9b30(p_dsAction)) { diff --git a/LEGO1/omni/src/notify/mxnotificationmanager.cpp b/LEGO1/omni/src/notify/mxnotificationmanager.cpp index 61e051f7..064f38f3 100644 --- a/LEGO1/omni/src/notify/mxnotificationmanager.cpp +++ b/LEGO1/omni/src/notify/mxnotificationmanager.cpp @@ -165,6 +165,7 @@ void MxNotificationManager::FlushPending(MxCore* p_listener) } // FUNCTION: LEGO1 0x100acd20 +// STUB: BETA10 0x1012666a void MxNotificationManager::Register(MxCore* p_listener) { AUTOLOCK(m_lock); diff --git a/LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp b/LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp index 0e34ed5a..04f06b63 100644 --- a/LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp +++ b/LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp @@ -4,8 +4,8 @@ #include "mxautolock.h" #include "mxdiskstreamprovider.h" #include "mxdsstreamingaction.h" +#include "mxmain.h" #include "mxmisc.h" -#include "mxomni.h" #include "mxticklemanager.h" #include diff --git a/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp b/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp index 3cf753d6..b3fad5fc 100644 --- a/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp +++ b/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp @@ -5,7 +5,7 @@ #include "mxdsbuffer.h" #include "mxdsfile.h" #include "mxdsstreamingaction.h" -#include "mxomni.h" +#include "mxmain.h" #include "mxramstreamprovider.h" #include "mxstreamcontroller.h" #include "mxstring.h" @@ -161,10 +161,11 @@ void MxDiskStreamProvider::VTable0x20(MxDSAction* p_action) } // FUNCTION: LEGO1 0x100d1750 +// FUNCTION: BETA10 0x101632b8 MxResult MxDiskStreamProvider::WaitForWorkToComplete() { while (m_remainingWork) { - m_busySemaphore.Wait(); + m_busySemaphore.Acquire(); if (m_unk0x35) { PerformWork(); } diff --git a/LEGO1/omni/src/stream/mxdsbuffer.cpp b/LEGO1/omni/src/stream/mxdsbuffer.cpp index 3634b6c7..0d49741a 100644 --- a/LEGO1/omni/src/stream/mxdsbuffer.cpp +++ b/LEGO1/omni/src/stream/mxdsbuffer.cpp @@ -3,8 +3,8 @@ #include "mxdiskstreamcontroller.h" #include "mxdschunk.h" #include "mxdsstreamingaction.h" +#include "mxmain.h" #include "mxmisc.h" -#include "mxomni.h" #include "mxstreamchunk.h" #include "mxstreamcontroller.h" #include "mxstreamer.h" diff --git a/LEGO1/omni/src/stream/mxramstreamprovider.cpp b/LEGO1/omni/src/stream/mxramstreamprovider.cpp index 966bec95..ecd1a6f9 100644 --- a/LEGO1/omni/src/stream/mxramstreamprovider.cpp +++ b/LEGO1/omni/src/stream/mxramstreamprovider.cpp @@ -3,7 +3,7 @@ #include "decomp.h" #include "mxdsbuffer.h" #include "mxdsfile.h" -#include "mxomni.h" +#include "mxmain.h" #include "mxstreamcontroller.h" #include "mxutilities.h" diff --git a/LEGO1/omni/src/system/mxautolock.cpp b/LEGO1/omni/src/system/mxautolock.cpp index 4508663e..227085dd 100644 --- a/LEGO1/omni/src/system/mxautolock.cpp +++ b/LEGO1/omni/src/system/mxautolock.cpp @@ -2,8 +2,19 @@ #include "mxcriticalsection.h" -// FUNCTION: LEGO1 0x100b8ed0 +#ifdef BETA10 // FUNCTION: BETA10 0x101386f0 +MxAutoLock::MxAutoLock(MxCriticalSection* p_criticalSection, const char* filename, int line) +{ + m_criticalSection = p_criticalSection; + m_currentThreadId = GetCurrentThreadId(); + + if (m_criticalSection != NULL) { + m_criticalSection->Enter(m_currentThreadId, filename, line); + } +} +#else +// FUNCTION: LEGO1 0x100b8ed0 MxAutoLock::MxAutoLock(MxCriticalSection* p_criticalSection) { m_criticalSection = p_criticalSection; @@ -12,6 +23,7 @@ MxAutoLock::MxAutoLock(MxCriticalSection* p_criticalSection) m_criticalSection->Enter(); } } +#endif // FUNCTION: LEGO1 0x100b8ef0 // FUNCTION: BETA10 0x10138744 diff --git a/LEGO1/omni/src/system/mxcriticalsection.cpp b/LEGO1/omni/src/system/mxcriticalsection.cpp index 7b982bd6..e940c847 100644 --- a/LEGO1/omni/src/system/mxcriticalsection.cpp +++ b/LEGO1/omni/src/system/mxcriticalsection.cpp @@ -22,14 +22,43 @@ MxCriticalSection::~MxCriticalSection() } } -// FUNCTION: LEGO1 0x100b6d80 +#ifdef BETA10 // FUNCTION: BETA10 0x1013c725 +void MxCriticalSection::Enter(unsigned long p_threadId, const char* filename, int line) +{ + DWORD result; + FILE* file; + + if (m_mutex != NULL) { + result = WaitForSingleObject(m_mutex, 5000); + if (result == WAIT_FAILED) { + file = fopen("C:\\DEADLOCK.TXT", "a"); + if (file != NULL) { + fprintf(file, "mutex timeout occurred!\n"); + fprintf(file, "file: %s, line: %d\n", filename, line); + fclose(file); + } + + abort(); + } + } + else { + EnterCriticalSection(&m_criticalSection); + } + + // There is way more structure in here, and the MxCriticalSection class is much larger in BETA10. + // The LEGO1 compilation is very unlikely to profit from a further decompilation here. +} +#else +// FUNCTION: LEGO1 0x100b6d80 void MxCriticalSection::Enter() { SDL_LockMutex(m_mutex); } +#endif // FUNCTION: LEGO1 0x100b6de0 +// FUNCTION: BETA10 0x1013c7ef void MxCriticalSection::Leave() { SDL_UnlockMutex(m_mutex); diff --git a/LEGO1/omni/src/system/mxsemaphore.cpp b/LEGO1/omni/src/system/mxsemaphore.cpp index a4db127b..2cd2016e 100644 --- a/LEGO1/omni/src/system/mxsemaphore.cpp +++ b/LEGO1/omni/src/system/mxsemaphore.cpp @@ -6,32 +6,46 @@ DECOMP_SIZE_ASSERT(MxSemaphore, 0x08) // FUNCTION: LEGO1 0x100c87d0 +// FUNCTION: BETA10 0x10159260 MxSemaphore::MxSemaphore() { m_semaphore = NULL; } // FUNCTION: LEGO1 0x100c8800 +// FUNCTION: BETA10 0x101592d5 MxResult MxSemaphore::Init(MxU32 p_initialCount, MxU32 p_maxCount) { // [library:synchronization] No support for max count, but shouldn't be necessary MxResult result = FAILURE; - if ((m_semaphore = SDL_CreateSemaphore(p_initialCount))) { - result = SUCCESS; + m_semaphore = SDL_CreateSemaphore(p_initialCount); + if (!m_semaphore) { + goto done; } + result = SUCCESS; + +done: return result; } // FUNCTION: LEGO1 0x100c8830 -void MxSemaphore::Wait() +// FUNCTION: BETA10 0x10159332 +void MxSemaphore::Acquire() { // [library:synchronization] Removed timeout since only INFINITE is ever requested SDL_WaitSemaphore(m_semaphore); } +// FUNCTION: BETA10 0x10159385 +void MxSemaphore::TryAcquire() +{ + // unused +} + // FUNCTION: LEGO1 0x100c8850 +// FUNCTION: BETA10 0x101593aa void MxSemaphore::Release() { // [library:synchronization] Removed release count since only 1 is ever requested diff --git a/LEGO1/omni/src/system/mxthread.cpp b/LEGO1/omni/src/system/mxthread.cpp index 96e64992..307db15a 100644 --- a/LEGO1/omni/src/system/mxthread.cpp +++ b/LEGO1/omni/src/system/mxthread.cpp @@ -7,6 +7,7 @@ DECOMP_SIZE_ASSERT(MxThread, 0x1c) // FUNCTION: LEGO1 0x100bf510 +// FUNCTION: BETA10 0x10147540 MxThread::MxThread() { m_thread = NULL; @@ -14,6 +15,7 @@ MxThread::MxThread() } // FUNCTION: LEGO1 0x100bf5a0 +// FUNCTION: BETA10 0x101475d0 MxThread::~MxThread() { if (m_thread) { @@ -22,46 +24,91 @@ MxThread::~MxThread() } // FUNCTION: LEGO1 0x100bf610 +// FUNCTION: BETA10 0x10147655 MxResult MxThread::Start(MxS32 p_stackSize, MxS32 p_flag) { MxResult result = FAILURE; - if (m_semaphore.Init(0, 1) == SUCCESS) { + if (m_semaphore.Init(0, 1) != SUCCESS) { + goto done; + } + + { const SDL_PropertiesID props = SDL_CreateProperties(); SDL_SetPointerProperty(props, SDL_PROP_THREAD_CREATE_ENTRY_FUNCTION_POINTER, (void*) MxThread::ThreadProc); SDL_SetPointerProperty(props, SDL_PROP_THREAD_CREATE_USERDATA_POINTER, this); SDL_SetNumberProperty(props, SDL_PROP_THREAD_CREATE_STACKSIZE_NUMBER, p_stackSize * 4); - if ((m_thread = SDL_CreateThreadWithProperties(props))) { - result = SUCCESS; + if (!(m_thread = SDL_CreateThreadWithProperties(props))) { + goto done; } SDL_DestroyProperties(props); } + result = SUCCESS; + +done: return result; } // FUNCTION: LEGO1 0x100bf660 +// FUNCTION: BETA10 0x101476ee void MxThread::Sleep(MxS32 p_milliseconds) { SDL_Delay(p_milliseconds); } +// FUNCTION: BETA10 0x10147710 +void MxThread::ResumeThread() +{ + // unused +} + +// FUNCTION: BETA10 0x10147733 +void MxThread::SuspendThread() +{ + // unused +} + +// FUNCTION: BETA10 0x10147756 +bool MxThread::TerminateThread(MxU32 p_exitCode) +{ + // unused + return false; +} + +// FUNCTION: BETA10 0x10147793 +MxS32 MxThread::GetThreadPriority(MxU16& p_priority) +{ + // unused + return -1; +} + +// FUNCTION: BETA10 0x101477c8 +bool MxThread::SetThreadPriority(MxU16 p_priority) +{ + // unused + return false; +} + // FUNCTION: LEGO1 0x100bf670 +// FUNCTION: BETA10 0x1014780a void MxThread::Terminate() { m_running = FALSE; - m_semaphore.Wait(); + m_semaphore.Acquire(); } // FUNCTION: LEGO1 0x100bf680 +// FUNCTION: BETA10 0x1014783b int MxThread::ThreadProc(void* p_thread) { return static_cast(p_thread)->Run(); } // FUNCTION: LEGO1 0x100bf690 +// FUNCTION: BETA10 0x10147855 MxResult MxThread::Run() { m_semaphore.Release(); diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index 2248a0ad..71a3808e 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -2,8 +2,8 @@ #include "mxbitmap.h" #include "mxdebug.h" +#include "mxmain.h" #include "mxmisc.h" -#include "mxomni.h" #include "mxpalette.h" #include "mxutilities.h" #include "mxvideomanager.h" @@ -482,7 +482,7 @@ void MxDisplaySurface::VTable0x28( tempSurface->Unlock(NULL); - if (m_videoParam.Flags().GetF1bit3()) { + if (m_videoParam.Flags().GetDoubleScaling()) { RECT destRect = {p_right, p_bottom, p_right + p_width * 2, p_bottom + p_height * 2}; m_ddSurface2->Blt(&destRect, tempSurface, NULL, DDBLT_WAIT | DDBLT_KEYSRC, NULL); } @@ -749,7 +749,7 @@ void MxDisplaySurface::DrawTransparentRLE( // FUNCTION: LEGO1 0x100bba50 void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p_top2, MxS32 p_width, MxS32 p_height) { - if (m_videoParam.Flags().GetF2bit1()) { + if (m_videoParam.Flags().GetEnabled()) { if (m_videoParam.Flags().GetFlipSurfaces()) { if (g_unk0x1010215c < 2) { g_unk0x1010215c++; @@ -1012,7 +1012,7 @@ void MxDisplaySurface::VTable0x24( MxU8* data = p_bitmap->GetStart(p_left, p_top); - if (m_videoParam.Flags().GetF1bit3()) { + if (m_videoParam.Flags().GetDoubleScaling()) { p_bottom *= 2; p_right *= 2; diff --git a/LEGO1/omni/src/video/mxflcpresenter.cpp b/LEGO1/omni/src/video/mxflcpresenter.cpp index 1bc8462e..4bb95fbb 100644 --- a/LEGO1/omni/src/video/mxflcpresenter.cpp +++ b/LEGO1/omni/src/video/mxflcpresenter.cpp @@ -13,8 +13,8 @@ DECOMP_SIZE_ASSERT(MxFlcPresenter, 0x68); MxFlcPresenter::MxFlcPresenter() { m_flcHeader = NULL; - SetBit1(FALSE); - SetBit2(FALSE); + SetUseSurface(FALSE); + SetUseVideoMemory(FALSE); } // FUNCTION: LEGO1 0x100b3420 diff --git a/LEGO1/omni/src/video/mxloopingflcpresenter.cpp b/LEGO1/omni/src/video/mxloopingflcpresenter.cpp index a828296c..c5f9c568 100644 --- a/LEGO1/omni/src/video/mxloopingflcpresenter.cpp +++ b/LEGO1/omni/src/video/mxloopingflcpresenter.cpp @@ -22,14 +22,14 @@ MxLoopingFlcPresenter::~MxLoopingFlcPresenter() void MxLoopingFlcPresenter::Init() { this->m_elapsedDuration = 0; - SetBit1(FALSE); - SetBit2(FALSE); + SetUseSurface(FALSE); + SetUseVideoMemory(FALSE); } // FUNCTION: LEGO1 0x100b4430 void MxLoopingFlcPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); Init(); m_criticalSection.Leave(); @@ -56,7 +56,7 @@ void MxLoopingFlcPresenter::NextFrame() } // FUNCTION: LEGO1 0x100b44c0 -void MxLoopingFlcPresenter::VTable0x88() +void MxLoopingFlcPresenter::LoadFrameIfRequired() { if (m_action->GetDuration() < m_elapsedDuration) { ProgressTickleState(e_freezing); @@ -72,7 +72,7 @@ void MxLoopingFlcPresenter::VTable0x88() // FUNCTION: LEGO1 0x100b4520 void MxLoopingFlcPresenter::RepeatingTickle() { - for (MxS16 i = 0; i < m_unk0x5c; i++) { + for (MxS16 i = 0; i < m_frameLoadTickleCount; i++) { if (!m_loopingChunkCursor->HasMatch()) { MxStreamChunk* chunk; MxStreamChunkListCursor cursor(m_loopingChunks); @@ -100,7 +100,7 @@ void MxLoopingFlcPresenter::RepeatingTickle() break; } - VTable0x88(); + LoadFrameIfRequired(); m_loopingChunkCursor->Next(chunk); @@ -117,7 +117,7 @@ MxResult MxLoopingFlcPresenter::AddToManager() MxBool locked = FALSE; if (MxFlcPresenter::AddToManager() == SUCCESS) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; result = SUCCESS; } diff --git a/LEGO1/omni/src/video/mxloopingsmkpresenter.cpp b/LEGO1/omni/src/video/mxloopingsmkpresenter.cpp index e99533bd..a74196b4 100644 --- a/LEGO1/omni/src/video/mxloopingsmkpresenter.cpp +++ b/LEGO1/omni/src/video/mxloopingsmkpresenter.cpp @@ -22,14 +22,14 @@ MxLoopingSmkPresenter::~MxLoopingSmkPresenter() void MxLoopingSmkPresenter::Init() { m_elapsedDuration = 0; - SetBit1(FALSE); - SetBit2(FALSE); + SetUseSurface(FALSE); + SetUseVideoMemory(FALSE); } // FUNCTION: LEGO1 0x100b49d0 void MxLoopingSmkPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); Init(); m_criticalSection.Leave(); @@ -39,7 +39,7 @@ void MxLoopingSmkPresenter::Destroy(MxBool p_fromDestructor) } // FUNCTION: LEGO1 0x100b4a00 -void MxLoopingSmkPresenter::VTable0x88() +void MxLoopingSmkPresenter::ResetCurrentFrameAtEnd() { // [library:libsmacker] Figure out if this functionality is still required } @@ -62,7 +62,7 @@ void MxLoopingSmkPresenter::NextFrame() } // FUNCTION: LEGO1 0x100b4a90 -void MxLoopingSmkPresenter::VTable0x8c() +void MxLoopingSmkPresenter::LoadFrameIfRequired() { if (m_action->GetDuration() < m_elapsedDuration) { ProgressTickleState(e_freezing); @@ -78,7 +78,7 @@ void MxLoopingSmkPresenter::VTable0x8c() // FUNCTION: LEGO1 0x100b4b00 void MxLoopingSmkPresenter::RepeatingTickle() { - for (MxS16 i = 0; i < m_unk0x5c; i++) { + for (MxS16 i = 0; i < m_frameLoadTickleCount; i++) { if (!m_loopingChunkCursor->HasMatch()) { MxStreamChunk* chunk; MxStreamChunkListCursor cursor(m_loopingChunks); @@ -106,7 +106,7 @@ void MxLoopingSmkPresenter::RepeatingTickle() break; } - VTable0x8c(); + LoadFrameIfRequired(); m_loopingChunkCursor->Next(chunk); diff --git a/LEGO1/omni/src/video/mxsmkpresenter.cpp b/LEGO1/omni/src/video/mxsmkpresenter.cpp index b530b2e2..42164c87 100644 --- a/LEGO1/omni/src/video/mxsmkpresenter.cpp +++ b/LEGO1/omni/src/video/mxsmkpresenter.cpp @@ -27,14 +27,14 @@ void MxSmkPresenter::Init() { m_currentFrame = 0; memset(&m_mxSmk, 0, sizeof(m_mxSmk)); - SetBit1(FALSE); - SetBit2(FALSE); + SetUseSurface(FALSE); + SetUseVideoMemory(FALSE); } // FUNCTION: LEGO1 0x100b3900 void MxSmkPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); MxSmk::Destroy(&m_mxSmk); Init(); @@ -75,7 +75,7 @@ void MxSmkPresenter::LoadFrame(MxStreamChunk* p_chunk) MxBool paletteChanged; m_currentFrame++; - VTable0x88(); + ResetCurrentFrameAtEnd(); MxRect32List rects(TRUE); MxSmk::LoadFrame(bitmapInfo, bitmapData, &m_mxSmk, chunkData, paletteChanged, m_currentFrame - 1, &rects); @@ -96,7 +96,7 @@ void MxSmkPresenter::LoadFrame(MxStreamChunk* p_chunk) } // FUNCTION: LEGO1 0x100b4260 -void MxSmkPresenter::VTable0x88() +void MxSmkPresenter::ResetCurrentFrameAtEnd() { // [library:libsmacker] Figure out if this functionality is still required } diff --git a/LEGO1/omni/src/video/mxstillpresenter.cpp b/LEGO1/omni/src/video/mxstillpresenter.cpp index 7ff98788..53a0427a 100644 --- a/LEGO1/omni/src/video/mxstillpresenter.cpp +++ b/LEGO1/omni/src/video/mxstillpresenter.cpp @@ -6,8 +6,8 @@ #include "mxdisplaysurface.h" #include "mxdsmediaaction.h" #include "mxdssubscriber.h" +#include "mxmain.h" #include "mxmisc.h" -#include "mxomni.h" #include "mxpalette.h" #include "mxutilities.h" #include "mxvideomanager.h" @@ -19,7 +19,7 @@ DECOMP_SIZE_ASSERT(MxStillPresenter, 0x6c); // FUNCTION: LEGO1 0x100b9c70 void MxStillPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_bitmapInfo) { delete[] ((MxU8*) m_bitmapInfo); @@ -81,12 +81,12 @@ void MxStillPresenter::LoadFrame(MxStreamChunk* p_chunk) MxRect32 rect(x, y, width + x, height + y); MVideoManager()->InvalidateRect(rect); - if (GetBit1()) { - undefined4 und = 0; - m_unk0x58 = MxOmni::GetInstance()->GetVideoManager()->GetDisplaySurface()->VTable0x44( + if (UseSurface()) { + undefined4 useVideoMemory = 0; + m_surface = MxOmni::GetInstance()->GetVideoManager()->GetDisplaySurface()->VTable0x44( m_frameBitmap, - &und, - GetBit3(), + &useVideoMemory, + DoNotWriteToSurface(), m_action->GetFlags() & MxDSAction::c_bit4 ); @@ -96,11 +96,11 @@ void MxStillPresenter::LoadFrame(MxStreamChunk* p_chunk) delete m_frameBitmap; m_frameBitmap = NULL; - if (m_unk0x58 && und) { - SetBit2(TRUE); + if (m_surface && useVideoMemory) { + SetUseVideoMemory(TRUE); } else { - SetBit2(FALSE); + SetUseVideoMemory(FALSE); } } } @@ -198,7 +198,7 @@ void MxStillPresenter::ParseExtra() MxPresenter::ParseExtra(); if (m_action->GetFlags() & MxDSAction::c_bit5) { - SetBit3(TRUE); + SetDoNotWriteToSurface(TRUE); } MxU16 extraLength; @@ -218,9 +218,9 @@ void MxStillPresenter::ParseExtra() } if (KeyValueStringParse(output, g_strBMP_ISMAP, extraCopy)) { - SetBit4(TRUE); - SetBit1(FALSE); - SetBit2(FALSE); + SetBitmapIsMap(TRUE); + SetUseSurface(FALSE); + SetUseVideoMemory(FALSE); } } } @@ -236,11 +236,11 @@ MxStillPresenter* MxStillPresenter::Clone() MxDSAction* action = GetAction()->Clone(); if (action && presenter->StartAction(NULL, action) == SUCCESS) { - presenter->SetBit0(GetBit0()); - presenter->SetBit1(GetBit1()); - presenter->SetBit2(GetBit2()); - presenter->SetBit3(GetBit3()); - presenter->SetBit4(GetBit4()); + presenter->SetLoadedFirstFrame(LoadedFirstFrame()); + presenter->SetUseSurface(UseSurface()); + presenter->SetUseVideoMemory(UseVideoMemory()); + presenter->SetDoNotWriteToSurface(DoNotWriteToSurface()); + presenter->SetBitmapIsMap(BitmapIsMap()); if (m_frameBitmap) { presenter->m_frameBitmap = new MxBitmap; @@ -250,8 +250,8 @@ MxStillPresenter* MxStillPresenter::Clone() } } - if (m_unk0x58) { - presenter->m_unk0x58 = MxDisplaySurface::CopySurface(m_unk0x58); + if (m_surface) { + presenter->m_surface = MxDisplaySurface::CopySurface(m_surface); } if (m_alpha) { diff --git a/LEGO1/omni/src/video/mxvideomanager.cpp b/LEGO1/omni/src/video/mxvideomanager.cpp index 8c75dc6a..40078e66 100644 --- a/LEGO1/omni/src/video/mxvideomanager.cpp +++ b/LEGO1/omni/src/video/mxvideomanager.cpp @@ -2,8 +2,8 @@ #include "mxautolock.h" #include "mxdisplaysurface.h" +#include "mxmain.h" #include "mxmisc.h" -#include "mxomni.h" #include "mxpalette.h" #include "mxpresenter.h" #include "mxregion.h" @@ -15,23 +15,27 @@ DECOMP_SIZE_ASSERT(MxVideoManager, 0x64) // FUNCTION: LEGO1 0x100be1f0 +// STUB: BETA10 0x1012ca40 MxVideoManager::MxVideoManager() { Init(); } // FUNCTION: LEGO1 0x100be270 +// FUNCTION: BETA10 0x1012dde0 void MxVideoManager::UpdateView(MxU32 p_x, MxU32 p_y, MxU32 p_width, MxU32 p_height) { } // FUNCTION: LEGO1 0x100be2a0 +// FUNCTION: BETA10 0x1012cad8 MxVideoManager::~MxVideoManager() { Destroy(TRUE); } // FUNCTION: LEGO1 0x100be320 +// FUNCTION: BETA10 0x1012cb66 MxResult MxVideoManager::Init() { m_pDirectDraw = NULL; @@ -44,6 +48,7 @@ MxResult MxVideoManager::Init() } // FUNCTION: LEGO1 0x100be340 +// FUNCTION: BETA10 0x1012cbca void MxVideoManager::Destroy(MxBool p_fromDestructor) { if (m_thread) { @@ -54,7 +59,7 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor) TickleManager()->UnregisterClient(this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_displaySurface) { delete m_displaySurface; @@ -81,7 +86,7 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor) m_criticalSection.Leave(); if (!p_fromDestructor) { - MxMediaManager::Destroy(); + MxPresentationManager::Destroy(); } } @@ -134,6 +139,7 @@ void MxVideoManager::SortPresenterList() } // FUNCTION: LEGO1 0x100be600 +// STUB: BETA10 0x1012cfbc MxResult MxVideoManager::VTable0x28( MxVideoParam& p_videoParam, LPDIRECTDRAW p_pDirectDraw, @@ -150,11 +156,11 @@ MxResult MxVideoManager::VTable0x28( m_unk0x60 = FALSE; - if (MxMediaManager::Create() != SUCCESS) { + if (MxPresentationManager::Create() != SUCCESS) { goto done; } - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; m_videoParam = p_videoParam; @@ -216,6 +222,7 @@ MxResult MxVideoManager::VTable0x28( } // FUNCTION: LEGO1 0x100be820 +// STUB: BETA10 0x1012d3f1 MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, MxBool p_createThread) { MxBool locked = FALSE; @@ -224,12 +231,12 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, m_unk0x60 = TRUE; - if (MxMediaManager::Create() != SUCCESS) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxMediaManager::Create failed"); + if (MxPresentationManager::Create() != SUCCESS) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxPresentationManager::Create failed"); goto done; } - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; m_videoParam = p_videoParam; @@ -308,6 +315,7 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, } // FUNCTION: LEGO1 0x100bea50 +// FUNCTION: BETA10 0x1012d85f void MxVideoManager::Destroy() { Destroy(FALSE); @@ -316,7 +324,7 @@ void MxVideoManager::Destroy() // FUNCTION: LEGO1 0x100bea60 void MxVideoManager::InvalidateRect(MxRect32& p_rect) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_region) { m_region->AddRect(p_rect); @@ -326,6 +334,7 @@ void MxVideoManager::InvalidateRect(MxRect32& p_rect) } // FUNCTION: LEGO1 0x100bea90 +// FUNCTION: BETA10 0x1012d8e3 MxResult MxVideoManager::Tickle() { AUTOLOCK(m_criticalSection); @@ -356,7 +365,7 @@ MxResult MxVideoManager::RealizePalette(MxPalette* p_palette) { PALETTEENTRY paletteEntries[256]; - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (p_palette && m_videoParam.GetPalette()) { p_palette->GetEntries(paletteEntries); diff --git a/LEGO1/omni/src/video/mxvideoparam.cpp b/LEGO1/omni/src/video/mxvideoparam.cpp index 9a095c4e..45a9a688 100644 --- a/LEGO1/omni/src/video/mxvideoparam.cpp +++ b/LEGO1/omni/src/video/mxvideoparam.cpp @@ -28,6 +28,8 @@ MxVideoParam::MxVideoParam(MxRect32& p_rect, MxPalette* p_palette, MxULong p_bac m_flags = p_flags; m_unk0x1c = 0; m_deviceId = NULL; + m_msaaSamples = 0; + m_anisotropic = 0.0f; } // FUNCTION: LEGO1 0x100becf0 @@ -41,6 +43,8 @@ MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam) m_unk0x1c = p_videoParam.m_unk0x1c; m_deviceId = NULL; SetDeviceName(p_videoParam.m_deviceId); + m_msaaSamples = p_videoParam.m_msaaSamples; + m_anisotropic = p_videoParam.m_anisotropic; } // FUNCTION: LEGO1 0x100bed50 @@ -82,6 +86,8 @@ MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam) m_flags = p_videoParam.m_flags; m_unk0x1c = p_videoParam.m_unk0x1c; SetDeviceName(p_videoParam.m_deviceId); + m_msaaSamples = p_videoParam.m_msaaSamples; + m_anisotropic = p_videoParam.m_anisotropic; return *this; } diff --git a/LEGO1/omni/src/video/mxvideopresenter.cpp b/LEGO1/omni/src/video/mxvideopresenter.cpp index e5ed4564..38662f05 100644 --- a/LEGO1/omni/src/video/mxvideopresenter.cpp +++ b/LEGO1/omni/src/video/mxvideopresenter.cpp @@ -93,19 +93,19 @@ void MxVideoPresenter::Init() { m_frameBitmap = NULL; m_alpha = NULL; - m_unk0x5c = 1; - m_unk0x58 = NULL; - m_unk0x60 = -1; - SetBit0(FALSE); + m_frameLoadTickleCount = 1; + m_surface = NULL; + m_frozenTime = -1; + SetLoadedFirstFrame(FALSE); if (MVideoManager() != NULL) { MVideoManager(); - SetBit1(TRUE); - SetBit2(FALSE); + SetUseSurface(TRUE); + SetUseVideoMemory(FALSE); } - SetBit3(FALSE); - SetBit4(FALSE); + SetDoNotWriteToSurface(FALSE); + SetBitmapIsMap(FALSE); } // FUNCTION: LEGO1 0x100b27b0 @@ -115,11 +115,11 @@ void MxVideoPresenter::Destroy(MxBool p_fromDestructor) MVideoManager()->UnregisterPresenter(*this); } - if (m_unk0x58) { - m_unk0x58->Release(); - m_unk0x58 = NULL; - SetBit1(FALSE); - SetBit2(FALSE); + if (m_surface) { + m_surface->Release(); + m_surface = NULL; + SetUseSurface(FALSE); + SetUseVideoMemory(FALSE); } if (MVideoManager() && (m_alpha || m_frameBitmap)) { @@ -183,7 +183,7 @@ MxBool MxVideoPresenter::IsHit(MxS32 p_x, MxS32 p_y) MxU8* pixel = m_frameBitmap->GetStart(p_x - rect.GetLeft(), p_y - rect.GetTop()); - if (GetBit4()) { + if (BitmapIsMap()) { return (MxBool) *pixel; } @@ -241,7 +241,7 @@ void MxVideoPresenter::PutFrame() LPDIRECTDRAWSURFACE ddSurface = displaySurface->GetDirectDrawSurface2(); if (m_action->GetFlags() & MxDSAction::c_bit5) { - if (m_unk0x58) { + if (m_surface) { RECT src, dest; src.top = 0; src.left = 0; @@ -255,10 +255,10 @@ void MxVideoPresenter::PutFrame() switch (PrepareRects(src, dest)) { case 0: - ddSurface->Blt(&dest, m_unk0x58, &src, DDBLT_KEYSRC, NULL); + ddSurface->Blt(&dest, m_surface, &src, DDBLT_KEYSRC, NULL); break; case 1: - ddSurface->BltFast(dest.left, dest.top, m_unk0x58, &src, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); + ddSurface->BltFast(dest.left, dest.top, m_surface, &src, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); } } else { @@ -277,7 +277,7 @@ void MxVideoPresenter::PutFrame() else { RECT src, dest; - if (m_unk0x58) { + if (m_surface) { src.left = 0; src.top = 0; src.right = GetWidth(); @@ -290,18 +290,18 @@ void MxVideoPresenter::PutFrame() } if (m_action->GetFlags() & MxDSAction::c_bit4) { - if (m_unk0x58) { + if (m_surface) { if (PrepareRects(src, dest) >= 0) { - ddSurface->Blt(&dest, m_unk0x58, &src, DDBLT_KEYSRC, NULL); + ddSurface->Blt(&dest, m_surface, &src, DDBLT_KEYSRC, NULL); } } else { displaySurface->VTable0x30(m_frameBitmap, 0, 0, GetX(), GetY(), GetWidth(), GetHeight(), FALSE); } } - else if (m_unk0x58) { + else if (m_surface) { if (PrepareRects(src, dest) >= 0) { - ddSurface->Blt(&dest, m_unk0x58, &src, DDBLT_NONE, NULL); + ddSurface->Blt(&dest, m_surface, &src, DDBLT_NONE, NULL); } } else { @@ -348,7 +348,7 @@ void MxVideoPresenter::StreamingTickle() } } else { - for (MxS16 i = 0; i < m_unk0x5c; i++) { + for (MxS16 i = 0; i < m_frameLoadTickleCount; i++) { if (!m_currentChunk) { MxMediaPresenter::StreamingTickle(); @@ -364,15 +364,15 @@ void MxVideoPresenter::StreamingTickle() LoadFrame(m_currentChunk); m_subscriber->FreeDataChunk(m_currentChunk); m_currentChunk = NULL; - SetBit0(TRUE); + SetLoadedFirstFrame(TRUE); if (m_currentTickleState != e_streaming) { break; } } - if (GetBit0()) { - m_unk0x5c = 5; + if (LoadedFirstFrame()) { + m_frameLoadTickleCount = 5; } } } @@ -392,7 +392,7 @@ void MxVideoPresenter::RepeatingTickle() } } else { - for (MxS16 i = 0; i < m_unk0x5c; i++) { + for (MxS16 i = 0; i < m_frameLoadTickleCount; i++) { if (!m_currentChunk) { MxMediaPresenter::RepeatingTickle(); @@ -407,15 +407,15 @@ void MxVideoPresenter::RepeatingTickle() LoadFrame(m_currentChunk); m_currentChunk = NULL; - SetBit0(TRUE); + SetLoadedFirstFrame(TRUE); if (m_currentTickleState != e_repeating) { break; } } - if (GetBit0()) { - m_unk0x5c = 5; + if (LoadedFirstFrame()) { + m_frameLoadTickleCount = 5; } } } @@ -428,11 +428,11 @@ void MxVideoPresenter::FreezingTickle() if (sustainTime != -1) { if (sustainTime) { - if (m_unk0x60 == -1) { - m_unk0x60 = m_action->GetElapsedTime(); + if (m_frozenTime == -1) { + m_frozenTime = m_action->GetElapsedTime(); } - if (m_action->GetElapsedTime() >= m_unk0x60 + ((MxDSMediaAction*) m_action)->GetSustainTime()) { + if (m_action->GetElapsedTime() >= m_frozenTime + ((MxDSMediaAction*) m_action)->GetSustainTime()) { ProgressTickleState(e_done); } } diff --git a/LEGO1/realtime/orientableroi.cpp b/LEGO1/realtime/orientableroi.cpp index 92c9ac9e..3c45e90f 100644 --- a/LEGO1/realtime/orientableroi.cpp +++ b/LEGO1/realtime/orientableroi.cpp @@ -153,6 +153,7 @@ void OrientableROI::UpdateWorldDataWithTransformAndChildren(const Matrix4& p_tra } // FUNCTION: LEGO1 0x100a5a30 +// FUNCTION: BETA10 0x10167d31 void OrientableROI::SetWorldVelocity(const Vector3& p_world_velocity) { m_world_velocity = p_world_velocity; diff --git a/extensions/include/extensions/textureloader.h b/extensions/include/extensions/textureloader.h index c476c7ff..a318c9b8 100644 --- a/extensions/include/extensions/textureloader.h +++ b/extensions/include/extensions/textureloader.h @@ -5,6 +5,7 @@ #include #include +#include namespace Extensions { @@ -14,10 +15,11 @@ class TextureLoader { static bool PatchTexture(LegoTextureInfo* p_textureInfo); static std::map options; + static std::vector excludedFiles; static bool enabled; static constexpr std::array, 1> defaults = { - {{"texture loader:texture path", "/textures/"}} + {{"texture loader:texture path", "/textures"}} }; private: diff --git a/extensions/src/textureloader.cpp b/extensions/src/textureloader.cpp index 07b53253..3fbf0f7d 100644 --- a/extensions/src/textureloader.cpp +++ b/extensions/src/textureloader.cpp @@ -3,6 +3,7 @@ using namespace Extensions; std::map TextureLoader::options; +std::vector TextureLoader::excludedFiles; bool TextureLoader::enabled = false; void TextureLoader::Initialize() @@ -97,13 +98,17 @@ bool TextureLoader::PatchTexture(LegoTextureInfo* p_textureInfo) SDL_Surface* TextureLoader::FindTexture(const char* p_name) { + if (std::find(excludedFiles.begin(), excludedFiles.end(), p_name) != excludedFiles.end()) { + return nullptr; + } + SDL_Surface* surface; const char* texturePath = options["texture loader:texture path"].c_str(); - MxString path = MxString(MxOmni::GetHD()) + texturePath + p_name + ".bmp"; + MxString path = MxString(MxOmni::GetHD()) + texturePath + "/" + p_name + ".bmp"; path.MapPathToFilesystem(); if (!(surface = SDL_LoadBMP(path.GetData()))) { - path = MxString(MxOmni::GetCD()) + texturePath + p_name + ".bmp"; + path = MxString(MxOmni::GetCD()) + texturePath + "/" + p_name + ".bmp"; path.MapPathToFilesystem(); surface = SDL_LoadBMP(path.GetData()); } diff --git a/miniwin/CMakeLists.txt b/miniwin/CMakeLists.txt index 517708ca..36f6f31c 100644 --- a/miniwin/CMakeLists.txt +++ b/miniwin/CMakeLists.txt @@ -44,16 +44,16 @@ if(NOT (VITA OR WINDOWS_STORE)) message(STATUS "🧩 OpenGL 1.x support not enabled — needs OpenGL") endif() - find_library(OPENGL_ES2_LIBRARY NAMES GLESv2) - if(EMSCRIPTEN OR OPENGL_ES2_LIBRARY) - message(STATUS "Found OpenGL: enabling OpenGL ES 2.x renderer") - target_sources(miniwin PRIVATE src/d3drm/backends/opengles2/renderer.cpp) - list(APPEND GRAPHICS_BACKENDS USE_OPENGLES2) - if(OPENGL_ES2_LIBRARY) - target_link_libraries(miniwin PRIVATE ${OPENGL_ES2_LIBRARY}) + find_library(OPENGL_ES3_LIBRARY NAMES GLESv2) + if(EMSCRIPTEN OR OPENGL_ES3_LIBRARY) + message(STATUS "Found OpenGL: enabling OpenGL ES 3.x renderer") + target_sources(miniwin PRIVATE src/d3drm/backends/opengles3/renderer.cpp) + list(APPEND GRAPHICS_BACKENDS USE_OPENGLES3) + if(OPENGL_ES3_LIBRARY) + target_link_libraries(miniwin PRIVATE ${OPENGL_ES3_LIBRARY}) endif() else() - message(STATUS "🧩 OpenGL ES 2.x support not enabled") + message(STATUS "🧩 OpenGL ES 3.x support not enabled") endif() endif() diff --git a/miniwin/include/miniwin/miniwind3d.h b/miniwin/include/miniwin/miniwind3d.h new file mode 100644 index 00000000..aea2e25c --- /dev/null +++ b/miniwin/include/miniwin/miniwind3d.h @@ -0,0 +1,10 @@ +#pragma once + +DEFINE_GUID(IID_IDirect3DMiniwin, 0xf8a97f2d, 0x9b3a, 0x4f1c, 0x9e, 0x8d, 0x6a, 0x5b, 0x4c, 0x3d, 0x2e, 0x1f); + +struct IDirect3DMiniwin : virtual public IUnknown { + virtual HRESULT RequestMSAA(DWORD msaaSamples) = 0; + virtual DWORD GetMSAASamples() const = 0; + virtual HRESULT RequestAnisotropic(float anisotropic) = 0; + virtual float GetAnisotropic() const = 0; +}; diff --git a/miniwin/src/d3drm/backends/opengl1/renderer.cpp b/miniwin/src/d3drm/backends/opengl1/renderer.cpp index 88b3b81b..2d4c14c9 100644 --- a/miniwin/src/d3drm/backends/opengl1/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengl1/renderer.cpp @@ -16,7 +16,7 @@ static_assert(sizeof(GL11_BridgeTexCoord) == sizeof(TexCoord), "GL11_BridgeTexCo static_assert(sizeof(GL11_BridgeSceneLight) == sizeof(SceneLight), "GL11_BridgeSceneLight is wrong size"); static_assert(sizeof(GL11_BridgeSceneVertex) == sizeof(D3DRMVERTEX), "GL11_BridgeSceneVertex is wrong size"); -Direct3DRMRenderer* OpenGL1Renderer::Create(DWORD width, DWORD height) +Direct3DRMRenderer* OpenGL1Renderer::Create(DWORD width, DWORD height, DWORD msaaSamples) { // We have to reset the attributes here after having enumerated the // OpenGL ES 2.0 renderer, or else SDL gets very confused by SDL_GL_DEPTH_SIZE @@ -28,6 +28,11 @@ Direct3DRMRenderer* OpenGL1Renderer::Create(DWORD width, DWORD height) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + if (msaaSamples > 1) { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaaSamples); + } + if (!DDWindow) { SDL_Log("No window handler"); return nullptr; diff --git a/miniwin/src/d3drm/backends/opengles2/renderer.cpp b/miniwin/src/d3drm/backends/opengles3/renderer.cpp similarity index 73% rename from miniwin/src/d3drm/backends/opengles2/renderer.cpp rename to miniwin/src/d3drm/backends/opengles3/renderer.cpp index e1c86a62..98cf6db5 100644 --- a/miniwin/src/d3drm/backends/opengles2/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengles3/renderer.cpp @@ -1,8 +1,8 @@ -#include "d3drmrenderer_opengles2.h" +#include "d3drmrenderer_opengles3.h" #include "meshutils.h" -#include #include +#include #include #include #include @@ -15,20 +15,29 @@ static GLuint CompileShader(GLenum type, const char* source) GLint success; glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { + GLint logLength = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + std::vector log(logLength); + glGetShaderInfoLog(shader, logLength, nullptr, log.data()); + SDL_Log("Shader compile error: %s", log.data()); + } + else { + SDL_Log("CompileShader (%s)", SDL_GetError()); + } glDeleteShader(shader); - SDL_Log("CompileShader (%s)", SDL_GetError()); return 0; } return shader; } -struct SceneLightGLES2 { +struct SceneLightGLES3 { float color[4]; float position[4]; float direction[4]; }; -Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) +Direct3DRMRenderer* OpenGLES3Renderer::Create(DWORD width, DWORD height, DWORD msaaSamples, float anisotropic) { // We have to reset the attributes here after having enumerated the // OpenGL ES 2.0 renderer, or else SDL gets very confused by SDL_GL_DEPTH_SIZE @@ -37,7 +46,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) // But ResetAttributes resets it to 16. SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); if (!DDWindow) { @@ -61,18 +70,20 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) glCullFace(GL_BACK); glFrontFace(GL_CW); - const char* vertexShaderSource = R"( - attribute vec3 a_position; - attribute vec3 a_normal; - attribute vec2 a_texCoord; + const char* vertexShaderSource = R"(#version 300 es + precision highp float; + + in vec3 a_position; + in vec3 a_normal; + in vec2 a_texCoord; uniform mat4 u_modelViewMatrix; uniform mat3 u_normalMatrix; uniform mat4 u_projectionMatrix; - varying vec3 v_viewPos; - varying vec3 v_normal; - varying vec2 v_texCoord; + out vec3 v_viewPos; + out vec3 v_normal; + out vec2 v_texCoord; void main() { vec4 viewPos = u_modelViewMatrix * vec4(a_position, 1.0); @@ -83,7 +94,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) } )"; - const char* fragmentShaderSource = R"( + const char* fragmentShaderSource = R"(#version 300 es precision mediump float; struct SceneLight { @@ -95,22 +106,22 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) uniform SceneLight u_lights[3]; uniform int u_lightCount; - varying vec3 v_viewPos; - varying vec3 v_normal; - varying vec2 v_texCoord; + in vec3 v_viewPos; + in vec3 v_normal; + in vec2 v_texCoord; uniform float u_shininess; uniform vec4 u_color; - uniform int u_useTexture; + uniform bool u_useTexture; uniform sampler2D u_texture; + out vec4 fragColor; + void main() { vec3 diffuse = vec3(0.0); vec3 specular = vec3(0.0); - for (int i = 0; i < 3; ++i) { - if (i >= u_lightCount) break; - + for (int i = 0; i < u_lightCount; ++i) { vec3 lightColor = u_lights[i].color.rgb; if (u_lights[i].position.w == 0.0 && u_lights[i].direction.w == 0.0) { @@ -134,7 +145,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) // Specular if (u_shininess > 0.0 && u_lights[i].direction.w == 1.0) { - vec3 viewVec = normalize(-v_viewPos); // Assuming camera at origin + vec3 viewVec = normalize(-v_viewPos); vec3 H = normalize(lightVec + viewVec); float dotNH = max(dot(v_normal, H), 0.0); float spec = pow(dotNH, u_shininess); @@ -145,13 +156,13 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) vec4 finalColor = u_color; finalColor.rgb = clamp(diffuse * u_color.rgb + specular, 0.0, 1.0); - if (u_useTexture != 0) { - vec4 texel = texture2D(u_texture, v_texCoord); + if (u_useTexture) { + vec4 texel = texture(u_texture, v_texCoord); finalColor.rgb = clamp(texel.rgb * finalColor.rgb, 0.0, 1.0); finalColor.a = texel.a; } - gl_FragColor = finalColor; + fragColor = finalColor; } )"; @@ -168,12 +179,12 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height) glDeleteShader(vs); glDeleteShader(fs); - return new OpenGLES2Renderer(width, height, context, shaderProgram); + return new OpenGLES3Renderer(width, height, msaaSamples, anisotropic, context, shaderProgram); } -GLES2MeshCacheEntry GLES2UploadMesh(const MeshGroup& meshGroup, bool forceUV = false) +GLES3MeshCacheEntry OpenGLES3Renderer::GLES3UploadMesh(const MeshGroup& meshGroup, bool forceUV) { - GLES2MeshCacheEntry cache{&meshGroup, meshGroup.version}; + GLES3MeshCacheEntry cache{&meshGroup, meshGroup.version}; cache.flat = meshGroup.quality == D3DRMRENDER_FLAT || meshGroup.quality == D3DRMRENDER_UNLITFLAT; @@ -211,18 +222,27 @@ GLES2MeshCacheEntry GLES2UploadMesh(const MeshGroup& meshGroup, bool forceUV = f std::vector normals(vertices.size()); std::transform(vertices.begin(), vertices.end(), normals.begin(), [](const D3DRMVERTEX& v) { return v.normal; }); + glGenVertexArrays(1, &cache.vao); + glBindVertexArray(cache.vao); + glGenBuffers(1, &cache.vboPositions); glBindBuffer(GL_ARRAY_BUFFER, cache.vboPositions); glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(D3DVECTOR), positions.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(m_posLoc); + glVertexAttribPointer(m_posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glGenBuffers(1, &cache.vboNormals); glBindBuffer(GL_ARRAY_BUFFER, cache.vboNormals); glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(D3DVECTOR), normals.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(m_normLoc); + glVertexAttribPointer(m_normLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr); if (meshGroup.texture || forceUV) { glGenBuffers(1, &cache.vboTexcoords); glBindBuffer(GL_ARRAY_BUFFER, cache.vboTexcoords); glBufferData(GL_ARRAY_BUFFER, texcoords.size() * sizeof(TexCoord), texcoords.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(m_texLoc); + glVertexAttribPointer(m_texLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr); } glGenBuffers(1, &cache.ibo); @@ -234,10 +254,12 @@ GLES2MeshCacheEntry GLES2UploadMesh(const MeshGroup& meshGroup, bool forceUV = f GL_STATIC_DRAW ); + glBindVertexArray(0); + return cache; } -bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI) +bool OpenGLES3Renderer::UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI) { SDL_Surface* surf = source; if (source->format != SDL_PIXELFORMAT_RGBA32) { @@ -262,11 +284,8 @@ bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - if (strstr((const char*) glGetString(GL_EXTENSIONS), "GL_EXT_texture_filter_anisotropic")) { - GLfloat maxAniso = 0.0f; - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso); - GLfloat desiredAniso = fminf(8.0f, maxAniso); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, desiredAniso); + if (m_anisotropic > 1.0f) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_anisotropic); } glGenerateMipmap(GL_TEXTURE_2D); } @@ -278,12 +297,52 @@ bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI) return true; } -OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext context, GLuint shaderProgram) - : m_context(context), m_shaderProgram(shaderProgram) +OpenGLES3Renderer::OpenGLES3Renderer( + DWORD width, + DWORD height, + DWORD msaaSamples, + float anisotropic, + SDL_GLContext context, + GLuint shaderProgram +) + : m_context(context), m_shaderProgram(shaderProgram), m_msaa(msaaSamples), m_anisotropic(anisotropic) { glGenFramebuffers(1, &m_fbo); glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); + GLint maxSamples; + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + if (m_msaa > maxSamples) { + m_msaa = maxSamples; + } + SDL_Log( + "MSAA is %s. Requested samples: %d, active samples: %d, max samples: %d", + m_msaa > 1 ? "on" : "off", + msaaSamples, + m_msaa, + maxSamples + ); + + if (m_msaa > 1) { + glGenFramebuffers(1, &m_resolveFBO); + } + + bool anisoAvailable = SDL_GL_ExtensionSupported("GL_EXT_texture_filter_anisotropic"); + GLfloat maxAniso = 0.0f; + if (anisoAvailable) { + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso); + } + if (m_anisotropic > maxAniso) { + m_anisotropic = maxAniso; + } + SDL_Log( + "Anisotropic is %s. Requested: %f, active: %f, max aniso: %f", + m_anisotropic > 1.0f ? "on" : "off", + anisotropic, + m_anisotropic, + maxAniso + ); + m_virtualWidth = width; m_virtualHeight = height; ViewportTransform viewportTransform = {1.0f, 0.0f, 0.0f}; @@ -310,14 +369,6 @@ OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext co } SDL_DestroySurface(dummySurface); - m_uiMesh.vertices = { - {{0.0f, 0.0f, 0.0f}, {0, 0, -1}, {0.0f, 0.0f}}, - {{1.0f, 0.0f, 0.0f}, {0, 0, -1}, {1.0f, 0.0f}}, - {{1.0f, 1.0f, 0.0f}, {0, 0, -1}, {1.0f, 1.0f}}, - {{0.0f, 1.0f, 0.0f}, {0, 0, -1}, {0.0f, 1.0f}} - }; - m_uiMesh.indices = {0, 1, 2, 0, 2, 3}; - m_uiMeshCache = GLES2UploadMesh(m_uiMesh, true); m_posLoc = glGetAttribLocation(m_shaderProgram, "a_position"); m_normLoc = glGetAttribLocation(m_shaderProgram, "a_normal"); m_texLoc = glGetAttribLocation(m_shaderProgram, "a_texCoord"); @@ -336,17 +387,35 @@ OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext co m_normalMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_normalMatrix"); m_projectionMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_projectionMatrix"); + m_uiMesh.vertices = { + {{0.0f, 0.0f, 0.0f}, {0, 0, -1}, {0.0f, 0.0f}}, + {{1.0f, 0.0f, 0.0f}, {0, 0, -1}, {1.0f, 0.0f}}, + {{1.0f, 1.0f, 0.0f}, {0, 0, -1}, {1.0f, 1.0f}}, + {{0.0f, 1.0f, 0.0f}, {0, 0, -1}, {0.0f, 1.0f}} + }; + m_uiMesh.indices = {0, 1, 2, 0, 2, 3}; + m_uiMeshCache = GLES3UploadMesh(m_uiMesh, true); + glUseProgram(m_shaderProgram); } -OpenGLES2Renderer::~OpenGLES2Renderer() +OpenGLES3Renderer::~OpenGLES3Renderer() { SDL_DestroySurface(m_renderedImage); + glDeleteTextures(1, &m_dummyTexture); glDeleteProgram(m_shaderProgram); + glDeleteRenderbuffers(1, &m_colorTarget); + glDeleteRenderbuffers(1, &m_depthTarget); + glDeleteFramebuffers(1, &m_fbo); + if (m_msaa > 1) { + glDeleteRenderbuffers(1, &m_resolveColor); + glDeleteFramebuffers(1, &m_resolveFBO); + } + SDL_GL_DestroyContext(m_context); } -void OpenGLES2Renderer::PushLights(const SceneLight* lightsArray, size_t count) +void OpenGLES3Renderer::PushLights(const SceneLight* lightsArray, size_t count) { if (count > 3) { SDL_Log("Unsupported number of lights (%d)", static_cast(count)); @@ -356,21 +425,21 @@ void OpenGLES2Renderer::PushLights(const SceneLight* lightsArray, size_t count) m_lights.assign(lightsArray, lightsArray + count); } -void OpenGLES2Renderer::SetFrustumPlanes(const Plane* frustumPlanes) +void OpenGLES3Renderer::SetFrustumPlanes(const Plane* frustumPlanes) { } -void OpenGLES2Renderer::SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) +void OpenGLES3Renderer::SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) { memcpy(&m_projection, projection, sizeof(D3DRMMATRIX4D)); } struct TextureDestroyContextGLS2 { - OpenGLES2Renderer* renderer; + OpenGLES3Renderer* renderer; Uint32 textureId; }; -void OpenGLES2Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture) +void OpenGLES3Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture) { auto* ctx = new TextureDestroyContextGLS2{this, id}; texture->AddDestroyCallback( @@ -388,7 +457,7 @@ void OpenGLES2Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* ); } -Uint32 OpenGLES2Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY) +Uint32 OpenGLES3Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY) { SDL_GL_MakeCurrent(DDWindow, m_context); auto texture = static_cast(iTexture); @@ -432,42 +501,43 @@ Uint32 OpenGLES2Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, return (Uint32) (m_textures.size() - 1); } -struct GLES2MeshDestroyContext { - OpenGLES2Renderer* renderer; +struct GLES3MeshDestroyContext { + OpenGLES3Renderer* renderer; Uint32 id; }; -void OpenGLES2Renderer::AddMeshDestroyCallback(Uint32 id, IDirect3DRMMesh* mesh) +void OpenGLES3Renderer::AddMeshDestroyCallback(Uint32 id, IDirect3DRMMesh* mesh) { - auto* ctx = new GLES2MeshDestroyContext{this, id}; + auto* ctx = new GLES3MeshDestroyContext{this, id}; mesh->AddDestroyCallback( [](IDirect3DRMObject*, void* arg) { - auto* ctx = static_cast(arg); + auto* ctx = static_cast(arg); auto& cache = ctx->renderer->m_meshs[ctx->id]; cache.meshGroup = nullptr; glDeleteBuffers(1, &cache.vboPositions); glDeleteBuffers(1, &cache.vboNormals); glDeleteBuffers(1, &cache.vboTexcoords); glDeleteBuffers(1, &cache.ibo); + glDeleteVertexArrays(1, &cache.vao); delete ctx; }, ctx ); } -Uint32 OpenGLES2Renderer::GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) +Uint32 OpenGLES3Renderer::GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) { for (Uint32 i = 0; i < m_meshs.size(); ++i) { auto& cache = m_meshs[i]; if (cache.meshGroup == meshGroup) { if (cache.version != meshGroup->version) { - cache = std::move(GLES2UploadMesh(*meshGroup)); + cache = std::move(GLES3UploadMesh(*meshGroup)); } return i; } } - auto newCache = GLES2UploadMesh(*meshGroup); + auto newCache = GLES3UploadMesh(*meshGroup); for (Uint32 i = 0; i < m_meshs.size(); ++i) { auto& cache = m_meshs[i]; @@ -483,7 +553,7 @@ Uint32 OpenGLES2Renderer::GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* mesh return (Uint32) (m_meshs.size() - 1); } -HRESULT OpenGLES2Renderer::BeginFrame() +HRESULT OpenGLES3Renderer::BeginFrame() { SDL_GL_MakeCurrent(DDWindow, m_context); m_dirty = true; @@ -495,7 +565,7 @@ HRESULT OpenGLES2Renderer::BeginFrame() glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); - SceneLightGLES2 lightData[3]; + SceneLightGLES3 lightData[3]; int lightCount = std::min(static_cast(m_lights.size()), 3); for (int i = 0; i < lightCount; ++i) { @@ -525,14 +595,14 @@ HRESULT OpenGLES2Renderer::BeginFrame() return DD_OK; } -void OpenGLES2Renderer::EnableTransparency() +void OpenGLES3Renderer::EnableTransparency() { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); } -void OpenGLES2Renderer::SubmitDraw( +void OpenGLES3Renderer::SubmitDraw( DWORD meshId, const D3DRMMATRIX4D& modelViewMatrix, const D3DRMMATRIX4D& worldMatrix, @@ -570,28 +640,12 @@ void OpenGLES2Renderer::SubmitDraw( glUniform1i(m_textureLoc, 0); } - glBindBuffer(GL_ARRAY_BUFFER, mesh.vboPositions); - glEnableVertexAttribArray(m_posLoc); - glVertexAttribPointer(m_posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - - glBindBuffer(GL_ARRAY_BUFFER, mesh.vboNormals); - glEnableVertexAttribArray(m_normLoc); - glVertexAttribPointer(m_normLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - - if (appearance.textureId != NO_TEXTURE_ID) { - glBindBuffer(GL_ARRAY_BUFFER, mesh.vboTexcoords); - glEnableVertexAttribArray(m_texLoc); - glVertexAttribPointer(m_texLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr); - } - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.ibo); + glBindVertexArray(mesh.vao); glDrawElements(GL_TRIANGLES, static_cast(mesh.indices.size()), GL_UNSIGNED_SHORT, nullptr); - - glDisableVertexAttribArray(m_normLoc); - glDisableVertexAttribArray(m_texLoc); + glBindVertexArray(0); } -HRESULT OpenGLES2Renderer::FinalizeFrame() +HRESULT OpenGLES3Renderer::FinalizeFrame() { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -599,7 +653,7 @@ HRESULT OpenGLES2Renderer::FinalizeFrame() return DD_OK; } -void OpenGLES2Renderer::Resize(int width, int height, const ViewportTransform& viewportTransform) +void OpenGLES3Renderer::Resize(int width, int height, const ViewportTransform& viewportTransform) { SDL_GL_MakeCurrent(DDWindow, m_context); m_width = width; @@ -610,37 +664,65 @@ void OpenGLES2Renderer::Resize(int width, int height, const ViewportTransform& v } m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_RGBA32); + if (m_colorTarget) { + glDeleteRenderbuffers(1, &m_colorTarget); + m_colorTarget = 0; + } + if (m_resolveColor) { + glDeleteRenderbuffers(1, &m_resolveColor); + m_resolveColor = 0; + } + if (m_depthTarget) { + glDeleteRenderbuffers(1, &m_depthTarget); + m_depthTarget = 0; + } + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); // Create color texture - glGenTextures(1, &m_colorTarget); - glBindTexture(GL_TEXTURE_2D, m_colorTarget); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTarget, 0); + glGenRenderbuffers(1, &m_colorTarget); + glBindRenderbuffer(GL_RENDERBUFFER, m_colorTarget); + if (m_msaa > 1) { + glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_msaa, GL_RGBA8, width, height); + } + else { + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height); + } + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorTarget); // Create depth renderbuffer glGenRenderbuffers(1, &m_depthTarget); glBindRenderbuffer(GL_RENDERBUFFER, m_depthTarget); - - if (SDL_GL_ExtensionSupported("GL_OES_depth24")) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, width, height); - } - else if (SDL_GL_ExtensionSupported("GL_OES_depth32")) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32_OES, width, height); + if (m_msaa > 1) { + glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_msaa, GL_DEPTH_COMPONENT24, width, height); } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); } glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthTarget); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + SDL_Log("FBO incomplete: 0x%X", status); + } + + if (m_msaa > 1) { + glBindFramebuffer(GL_FRAMEBUFFER, m_resolveFBO); + glGenRenderbuffers(1, &m_resolveColor); + glBindRenderbuffer(GL_RENDERBUFFER, m_resolveColor); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_resolveColor); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + SDL_Log("Resolve FBO incomplete: 0x%X", status); + } + } + + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); glViewport(0, 0, m_width, m_height); } -void OpenGLES2Renderer::Clear(float r, float g, float b) +void OpenGLES3Renderer::Clear(float r, float g, float b) { SDL_GL_MakeCurrent(DDWindow, m_context); m_dirty = true; @@ -653,71 +735,33 @@ void OpenGLES2Renderer::Clear(float r, float g, float b) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void OpenGLES2Renderer::Flip() +void OpenGLES3Renderer::Flip() { SDL_GL_MakeCurrent(DDWindow, m_context); if (!m_dirty) { return; } - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - glDisable(GL_DEPTH_TEST); - glFrontFace(GL_CCW); - glDepthMask(GL_FALSE); - - glUniform4f(m_colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); - glUniform1f(m_shinLoc, 0.0f); - - float ambient[] = {1.0f, 1.0f, 1.0f, 1.0f}; - float blank[] = {0.0f, 0.0f, 0.0f, 0.0f}; - glUniform4fv(u_lightLocs[0][0], 1, ambient); - glUniform4fv(u_lightLocs[0][1], 1, blank); - glUniform4fv(u_lightLocs[0][2], 1, blank); - glUniform1i(m_lightCountLoc, 1); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_colorTarget); - glUniform1i(m_textureLoc, 0); - glUniform1i(m_useTextureLoc, 1); - - D3DRMMATRIX4D projection; - D3DRMMATRIX4D modelViewMatrix = { - {(float) m_width, 0.0f, 0.0f, 0.0f}, - {0.0f, (float) -m_height, 0.0f, 0.0f}, - {0.0f, 0.0f, 1.0f, 0.0f}, - {0.0f, (float) m_height, 0.0f, 1.0f} - }; - glUniformMatrix4fv(m_modelViewMatrixLoc, 1, GL_FALSE, &modelViewMatrix[0][0]); - Matrix3x3 identity = {{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}}; - glUniformMatrix3fv(m_normalMatrixLoc, 1, GL_FALSE, &identity[0][0]); - CreateOrthographicProjection((float) m_width, (float) m_height, projection); - glUniformMatrix4fv(m_projectionMatrixLoc, 1, GL_FALSE, &projection[0][0]); + glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + // This is a workaround for what is (presumably) a driver bug in some WebGL environments (Android Chrome) + // During transitions, the screen would sometimes (randomly) briefly be cleared / flicker black when using + // glBlitFramebuffer. Any write to the back buffer before that fixes this issue. The following should have minimal + // performance impact. + glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, 1, 1); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glBindBuffer(GL_ARRAY_BUFFER, m_uiMeshCache.vboPositions); - glEnableVertexAttribArray(m_posLoc); - glVertexAttribPointer(m_posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - - glBindBuffer(GL_ARRAY_BUFFER, m_uiMeshCache.vboTexcoords); - glEnableVertexAttribArray(m_texLoc); - glVertexAttribPointer(m_texLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiMeshCache.ibo); - glDrawElements(GL_TRIANGLES, static_cast(m_uiMeshCache.indices.size()), GL_UNSIGNED_SHORT, nullptr); - - glDisableVertexAttribArray(m_texLoc); + glBlitFramebuffer(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); SDL_GL_SwapWindow(DDWindow); - glFrontFace(GL_CW); m_dirty = false; } -void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) +void OpenGLES3Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { SDL_GL_MakeCurrent(DDWindow, m_context); m_dirty = true; @@ -739,7 +783,7 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c SDL_Rect expandedDstRect; if (textureId != NO_TEXTURE_ID) { - const GLES2TextureCacheEntry& texture = m_textures[textureId]; + const GLES3TextureCacheEntry& texture = m_textures[textureId]; float scaleX = static_cast(dstRect.w) / srcRect.w; float scaleY = static_cast(dstRect.h) / srcRect.h; expandedDstRect = { @@ -790,26 +834,27 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c static_cast(std::round(dstRect.h * m_viewportTransform.scale)) ); - glBindBuffer(GL_ARRAY_BUFFER, m_uiMeshCache.vboPositions); - glEnableVertexAttribArray(m_posLoc); - glVertexAttribPointer(m_posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - - glBindBuffer(GL_ARRAY_BUFFER, m_uiMeshCache.vboTexcoords); - glEnableVertexAttribArray(m_texLoc); - glVertexAttribPointer(m_texLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiMeshCache.ibo); + glBindVertexArray(m_uiMeshCache.vao); glDrawElements(GL_TRIANGLES, static_cast(m_uiMeshCache.indices.size()), GL_UNSIGNED_SHORT, nullptr); + glBindVertexArray(0); - glDisableVertexAttribArray(m_texLoc); glDisable(GL_SCISSOR_TEST); } -void OpenGLES2Renderer::Download(SDL_Surface* target) +void OpenGLES3Renderer::Download(SDL_Surface* target) { glFinish(); - glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); + if (m_msaa > 1) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolveFBO); + glBlitFramebuffer(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_FRAMEBUFFER, m_resolveFBO); + } + else { + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); + } + glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_renderedImage->pixels); SDL_Rect srcRect = { @@ -839,7 +884,7 @@ void OpenGLES2Renderer::Download(SDL_Surface* target) SDL_DestroySurface(bufferClone); } -void OpenGLES2Renderer::SetDither(bool dither) +void OpenGLES3Renderer::SetDither(bool dither) { if (dither) { glEnable(GL_DITHER); diff --git a/miniwin/src/d3drm/d3drm.cpp b/miniwin/src/d3drm/d3drm.cpp index 7328d21c..3b4d5c9d 100644 --- a/miniwin/src/d3drm/d3drm.cpp +++ b/miniwin/src/d3drm/d3drm.cpp @@ -132,7 +132,11 @@ HRESULT Direct3DRMImpl::CreateDeviceFromSurface( DDSDesc.dwSize = sizeof(DDSURFACEDESC); surface->GetSurfaceDesc(&DDSDesc); - DDRenderer = CreateDirect3DRMRenderer(DDSDesc, guid); + IDirect3DMiniwin* miniwind3d = nullptr; + dd->QueryInterface(IID_IDirect3DMiniwin, (void**) &miniwind3d); + SDL_assert(miniwind3d); + + DDRenderer = CreateDirect3DRMRenderer(miniwind3d, DDSDesc, guid); if (!DDRenderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized"); return E_NOINTERFACE; diff --git a/miniwin/src/d3drm/d3drmdevice.cpp b/miniwin/src/d3drm/d3drmdevice.cpp index e3190692..2b062d50 100644 --- a/miniwin/src/d3drm/d3drmdevice.cpp +++ b/miniwin/src/d3drm/d3drmdevice.cpp @@ -185,7 +185,8 @@ bool Direct3DRMDevice2Impl::ConvertEventToRenderCoordinates(SDL_Event* event) } case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_DOWN: - case SDL_EVENT_FINGER_UP: { + case SDL_EVENT_FINGER_UP: + case SDL_EVENT_FINGER_CANCELED: { float x = (event->tfinger.x * m_windowWidth - m_viewportTransform.offsetX) / m_viewportTransform.scale; float y = (event->tfinger.y * m_windowHeight - m_viewportTransform.offsetY) / m_viewportTransform.scale; event->tfinger.x = x / m_virtualWidth; diff --git a/miniwin/src/d3drm/d3drmrenderer.cpp b/miniwin/src/d3drm/d3drmrenderer.cpp index 4eaaf619..b4ff5ec3 100644 --- a/miniwin/src/d3drm/d3drmrenderer.cpp +++ b/miniwin/src/d3drm/d3drmrenderer.cpp @@ -2,8 +2,8 @@ #ifdef USE_OPENGL1 #include "d3drmrenderer_opengl1.h" #endif -#ifdef USE_OPENGLES2 -#include "d3drmrenderer_opengles2.h" +#ifdef USE_OPENGLES3 +#include "d3drmrenderer_opengles3.h" #endif #ifdef USE_CITRO3D #include "d3drmrenderer_citro3d.h" @@ -21,7 +21,11 @@ #include "d3drmrenderer_gxm.h" #endif -Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const GUID* guid) +Direct3DRMRenderer* CreateDirect3DRMRenderer( + const IDirect3DMiniwin* d3d, + const DDSURFACEDESC& DDSDesc, + const GUID* guid +) { #ifdef USE_SDL_GPU if (SDL_memcmp(guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) { @@ -33,14 +37,19 @@ Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const return new Direct3DRMSoftwareRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight); } #endif -#ifdef USE_OPENGLES2 - if (SDL_memcmp(guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) { - return OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); +#ifdef USE_OPENGLES3 + if (SDL_memcmp(guid, &OpenGLES3_GUID, sizeof(GUID)) == 0) { + return OpenGLES3Renderer::Create( + DDSDesc.dwWidth, + DDSDesc.dwHeight, + d3d->GetMSAASamples(), + d3d->GetAnisotropic() + ); } #endif #ifdef USE_OPENGL1 if (SDL_memcmp(guid, &OpenGL1_GUID, sizeof(GUID)) == 0) { - return OpenGL1Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); + return OpenGL1Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight, d3d->GetMSAASamples()); } #endif #ifdef USE_CITRO3D @@ -61,16 +70,16 @@ Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const return nullptr; } -void Direct3DRMRenderer_EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) +void Direct3DRMRenderer_EnumDevices(const IDirect3DMiniwin* d3d, LPD3DENUMDEVICESCALLBACK cb, void* ctx) { #ifdef USE_SDL_GPU Direct3DRMSDL3GPU_EnumDevice(cb, ctx); #endif -#ifdef USE_OPENGLES2 - OpenGLES2Renderer_EnumDevice(cb, ctx); +#ifdef USE_OPENGLES3 + OpenGLES3Renderer_EnumDevice(d3d, cb, ctx); #endif #ifdef USE_OPENGL1 - OpenGL1Renderer_EnumDevice(cb, ctx); + OpenGL1Renderer_EnumDevice(d3d, cb, ctx); #endif #ifdef USE_CITRO3D Citro3DRenderer_EnumDevice(cb, ctx); diff --git a/miniwin/src/ddraw/ddraw.cpp b/miniwin/src/ddraw/ddraw.cpp index 264ceeb1..b28a105b 100644 --- a/miniwin/src/ddraw/ddraw.cpp +++ b/miniwin/src/ddraw/ddraw.cpp @@ -29,6 +29,11 @@ HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject) *ppvObject = static_cast(this); return S_OK; } + if (SDL_memcmp(&riid, &IID_IDirect3DMiniwin, sizeof(GUID)) == 0) { + this->IUnknown::AddRef(); + *ppvObject = static_cast(this); + return S_OK; + } MINIWIN_NOT_IMPLEMENTED(); return E_NOINTERFACE; } @@ -220,7 +225,7 @@ void EnumDevice( HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) { - Direct3DRMRenderer_EnumDevices(cb, ctx); + Direct3DRMRenderer_EnumDevices(this, cb, ctx); return S_OK; } @@ -317,7 +322,7 @@ HRESULT DirectDrawImpl::CreateDevice( DDSDesc.dwSize = sizeof(DDSURFACEDESC); pBackBuffer->GetSurfaceDesc(&DDSDesc); - DDRenderer = CreateDirect3DRMRenderer(DDSDesc, &guid); + DDRenderer = CreateDirect3DRMRenderer(this, DDSDesc, &guid); if (!DDRenderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized"); return E_NOINTERFACE; diff --git a/miniwin/src/internal/d3drmrenderer.h b/miniwin/src/internal/d3drmrenderer.h index 85b2d1b9..7c19a8b4 100644 --- a/miniwin/src/internal/d3drmrenderer.h +++ b/miniwin/src/internal/d3drmrenderer.h @@ -3,6 +3,7 @@ #include "d3drmmesh_impl.h" #include "mathutils.h" #include "miniwin/d3drm.h" +#include "miniwin/miniwind3d.h" #include "miniwin/miniwindevice.h" #include "structs.h" @@ -61,5 +62,9 @@ class Direct3DRMRenderer : public IDirect3DDevice2 { ViewportTransform m_viewportTransform; }; -Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const GUID* guid); -void Direct3DRMRenderer_EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx); +Direct3DRMRenderer* CreateDirect3DRMRenderer( + const IDirect3DMiniwin* d3d, + const DDSURFACEDESC& DDSDesc, + const GUID* guid +); +void Direct3DRMRenderer_EnumDevices(const IDirect3DMiniwin* d3d, LPD3DENUMDEVICESCALLBACK cb, void* ctx); diff --git a/miniwin/src/internal/d3drmrenderer_opengl1.h b/miniwin/src/internal/d3drmrenderer_opengl1.h index 2f1c8173..894fa10c 100644 --- a/miniwin/src/internal/d3drmrenderer_opengl1.h +++ b/miniwin/src/internal/d3drmrenderer_opengl1.h @@ -11,7 +11,7 @@ DEFINE_GUID(OpenGL1_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x class OpenGL1Renderer : public Direct3DRMRenderer { public: - static Direct3DRMRenderer* Create(DWORD width, DWORD height); + static Direct3DRMRenderer* Create(DWORD width, DWORD height, DWORD msaaSamples); OpenGL1Renderer(DWORD width, DWORD height, SDL_GLContext context); ~OpenGL1Renderer() override; @@ -54,9 +54,9 @@ class OpenGL1Renderer : public Direct3DRMRenderer { ViewportTransform m_viewportTransform; }; -inline static void OpenGL1Renderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx) +inline static void OpenGL1Renderer_EnumDevice(const IDirect3DMiniwin* d3d, LPD3DENUMDEVICESCALLBACK cb, void* ctx) { - Direct3DRMRenderer* device = OpenGL1Renderer::Create(640, 480); + Direct3DRMRenderer* device = OpenGL1Renderer::Create(640, 480, d3d->GetMSAASamples()); if (!device) { return; } diff --git a/miniwin/src/internal/d3drmrenderer_opengles2.h b/miniwin/src/internal/d3drmrenderer_opengles3.h similarity index 69% rename from miniwin/src/internal/d3drmrenderer_opengles2.h rename to miniwin/src/internal/d3drmrenderer_opengles3.h index d4985f32..e3f3f59d 100644 --- a/miniwin/src/internal/d3drmrenderer_opengles2.h +++ b/miniwin/src/internal/d3drmrenderer_opengles3.h @@ -4,13 +4,13 @@ #include "d3drmtexture_impl.h" #include "ddraw_impl.h" -#include +#include #include #include -DEFINE_GUID(OpenGLES2_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04); +DEFINE_GUID(OpenGLES3_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04); -struct GLES2TextureCacheEntry { +struct GLES3TextureCacheEntry { IDirect3DRMTexture* texture; Uint32 version; GLuint glTextureId; @@ -18,7 +18,7 @@ struct GLES2TextureCacheEntry { uint16_t height; }; -struct GLES2MeshCacheEntry { +struct GLES3MeshCacheEntry { const MeshGroup* meshGroup; int version; bool flat; @@ -28,13 +28,21 @@ struct GLES2MeshCacheEntry { GLuint vboNormals; GLuint vboTexcoords; GLuint ibo; + GLuint vao; }; -class OpenGLES2Renderer : public Direct3DRMRenderer { +class OpenGLES3Renderer : public Direct3DRMRenderer { public: - static Direct3DRMRenderer* Create(DWORD width, DWORD height); - OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext context, GLuint shaderProgram); - ~OpenGLES2Renderer() override; + static Direct3DRMRenderer* Create(DWORD width, DWORD height, DWORD msaaSamples, float anisotropic); + OpenGLES3Renderer( + DWORD width, + DWORD height, + DWORD msaaSamples, + float anisotropic, + SDL_GLContext context, + GLuint shaderProgram + ); + ~OpenGLES3Renderer() override; void PushLights(const SceneLight* lightsArray, size_t count) override; void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override; @@ -62,18 +70,24 @@ class OpenGLES2Renderer : public Direct3DRMRenderer { private: void AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture); void AddMeshDestroyCallback(Uint32 id, IDirect3DRMMesh* mesh); + GLES3MeshCacheEntry GLES3UploadMesh(const MeshGroup& meshGroup, bool forceUV = false); + bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI); MeshGroup m_uiMesh; - GLES2MeshCacheEntry m_uiMeshCache; - std::vector m_textures; - std::vector m_meshs; + GLES3MeshCacheEntry m_uiMeshCache; + std::vector m_textures; + std::vector m_meshs; D3DRMMATRIX4D m_projection; SDL_Surface* m_renderedImage = nullptr; bool m_dirty = false; std::vector m_lights; SDL_GLContext m_context; + uint32_t m_msaa; + float m_anisotropic; GLuint m_fbo; + GLuint m_resolveFBO; GLuint m_colorTarget; + GLuint m_resolveColor = 0; GLuint m_depthTarget; GLuint m_shaderProgram; GLuint m_dummyTexture; @@ -92,35 +106,25 @@ class OpenGLES2Renderer : public Direct3DRMRenderer { ViewportTransform m_viewportTransform; }; -inline static void OpenGLES2Renderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx) +inline static void OpenGLES3Renderer_EnumDevice(const IDirect3DMiniwin* d3d, LPD3DENUMDEVICESCALLBACK cb, void* ctx) { - Direct3DRMRenderer* device = OpenGLES2Renderer::Create(640, 480); + Direct3DRMRenderer* device = OpenGLES3Renderer::Create(640, 480, d3d->GetMSAASamples(), d3d->GetAnisotropic()); if (!device) { return; } + delete device; + D3DDEVICEDESC halDesc = {}; halDesc.dcmColorModel = D3DCOLOR_RGB; halDesc.dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH; - halDesc.dwDeviceZBufferBitDepth = DDBD_16; + halDesc.dwDeviceZBufferBitDepth = DDBD_24; halDesc.dwDeviceRenderBitDepth = DDBD_32; halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND; halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR; - const char* extensions = (const char*) glGetString(GL_EXTENSIONS); - if (extensions) { - if (strstr(extensions, "GL_OES_depth24")) { - halDesc.dwDeviceZBufferBitDepth |= DDBD_24; - } - if (strstr(extensions, "GL_OES_depth32")) { - halDesc.dwDeviceZBufferBitDepth |= DDBD_32; - } - } - - delete device; - D3DDEVICEDESC helDesc = {}; - EnumDevice(cb, ctx, "OpenGL ES 2.0 HAL", &halDesc, &helDesc, OpenGLES2_GUID); + EnumDevice(cb, ctx, "OpenGL ES 3.0 HAL", &halDesc, &helDesc, OpenGLES3_GUID); } diff --git a/miniwin/src/internal/ddraw_impl.h b/miniwin/src/internal/ddraw_impl.h index 4adfb4a5..0da2d883 100644 --- a/miniwin/src/internal/ddraw_impl.h +++ b/miniwin/src/internal/ddraw_impl.h @@ -4,6 +4,7 @@ #include "framebuffer_impl.h" #include "miniwin/d3d.h" #include "miniwin/ddraw.h" +#include "miniwin/miniwind3d.h" #include @@ -15,7 +16,7 @@ inline static SDL_Rect ConvertRect(const RECT* r) return {r->left, r->top, r->right - r->left, r->bottom - r->top}; } -struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 { +struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2, public IDirect3DMiniwin { // IUnknown interface HRESULT QueryInterface(const GUID& riid, void** ppvObject) override; // IDirectDraw interface @@ -45,11 +46,26 @@ struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 { HRESULT CreateDevice(const GUID& guid, IDirectDrawSurface* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) override; HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) override; + // IDirect3DMiniwin interface + HRESULT RequestMSAA(DWORD msaaSamples) override + { + m_msaaSamples = msaaSamples; + return DD_OK; + } + DWORD GetMSAASamples() const override { return m_msaaSamples; } + HRESULT RequestAnisotropic(float anisotropic) override + { + m_anisotropic = anisotropic; + return DD_OK; + } + float GetAnisotropic() const override { return m_anisotropic; } private: FrameBufferImpl* m_frameBuffer; int m_virtualWidth = 0; int m_virtualHeight = 0; + DWORD m_msaaSamples = 0; + float m_anisotropic = 0.0f; }; HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context);