diff --git a/CONFIG/MainDlg.cpp b/CONFIG/MainDlg.cpp index e2c526f6..828395bd 100644 --- a/CONFIG/MainDlg.cpp +++ b/CONFIG/MainDlg.cpp @@ -59,6 +59,7 @@ CMainDialog::CMainDialog(QWidget* pParent) : QDialog(pParent) connect(m_ui->sound3DCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckbox3DSound); connect(m_ui->joystickCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxJoystick); connect(m_ui->fullscreenCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxFullscreen); + connect(m_ui->transitionTypeComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::TransitionTypeChanged); 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); @@ -212,6 +213,7 @@ void CMainDialog::UpdateInterface() m_ui->joystickCheckBox->setChecked(currentConfigApp->m_use_joystick); m_ui->musicCheckBox->setChecked(currentConfigApp->m_music); m_ui->fullscreenCheckBox->setChecked(currentConfigApp->m_full_screen); + 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)); } @@ -296,6 +298,13 @@ void CMainDialog::OnCheckboxFullscreen(bool checked) UpdateInterface(); } +void CMainDialog::TransitionTypeChanged(int index) +{ + currentConfigApp->m_transition_type = index; + m_modified = true; + UpdateInterface(); +} + void CMainDialog::SelectDataPathDialog() { QString data_path = QString::fromStdString(currentConfigApp->m_cd_path); diff --git a/CONFIG/MainDlg.h b/CONFIG/MainDlg.h index 372a1156..72062486 100644 --- a/CONFIG/MainDlg.h +++ b/CONFIG/MainDlg.h @@ -43,6 +43,7 @@ private slots: void OnCheckboxJoystick(bool checked); void OnCheckboxMusic(bool checked); void OnCheckboxFullscreen(bool checked); + void TransitionTypeChanged(int index); void accept() override; void reject() override; void launch(); diff --git a/CONFIG/config.cpp b/CONFIG/config.cpp index 9030ae67..b4435298 100644 --- a/CONFIG/config.cpp +++ b/CONFIG/config.cpp @@ -70,6 +70,7 @@ bool CConfigApp::InitInstance() m_driver = NULL; m_device = NULL; m_full_screen = TRUE; + m_transition_type = 3; // 3: Mosaic m_wide_view_angle = TRUE; m_use_joystick = TRUE; m_music = TRUE; @@ -153,6 +154,7 @@ bool CConfigApp::ReadRegisterSettings() m_display_bit_depth = iniparser_getint(dict, "isle:Display Bit Depth", -1); m_flip_surfaces = iniparser_getboolean(dict, "isle:Flip Surfaces", m_flip_surfaces); m_full_screen = iniparser_getboolean(dict, "isle:Full Screen", m_full_screen); + m_transition_type = iniparser_getint(dict, "isle:Transition Type", m_transition_type); m_3d_video_ram = iniparser_getboolean(dict, "isle:Back Buffers in Video RAM", m_3d_video_ram); m_wide_view_angle = iniparser_getboolean(dict, "isle:Wide View Angle", m_wide_view_angle); m_3d_sound = iniparser_getboolean(dict, "isle:3DSound", m_3d_sound); @@ -308,6 +310,8 @@ void CConfigApp::WriteRegisterSettings() const SetIniBool(dict, "isle:Full Screen", m_full_screen); SetIniBool(dict, "isle:Wide View Angle", m_wide_view_angle); + SetIniInt(dict, "isle:Transition Type", m_transition_type); + SetIniBool(dict, "isle:3DSound", m_3d_sound); SetIniBool(dict, "isle:Music", m_music); diff --git a/CONFIG/config.h b/CONFIG/config.h index a621655a..dffc2b6c 100644 --- a/CONFIG/config.h +++ b/CONFIG/config.h @@ -65,6 +65,7 @@ class CConfigApp { int m_display_bit_depth; bool m_flip_surfaces; bool m_full_screen; + int m_transition_type; bool m_3d_video_ram; bool m_wide_view_angle; bool m_3d_sound; diff --git a/CONFIG/res/maindialog.ui b/CONFIG/res/maindialog.ui index c2d429ae..66e2b52e 100644 --- a/CONFIG/res/maindialog.ui +++ b/CONFIG/res/maindialog.ui @@ -57,7 +57,7 @@ false - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter @@ -129,10 +129,10 @@ Save Path: - Qt::PlainText + Qt::TextFormat::PlainText - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter @@ -162,10 +162,10 @@ Data Path: - Qt::PlainText + Qt::TextFormat::PlainText - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter @@ -241,7 +241,7 @@ Maximum LOD - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter @@ -262,10 +262,10 @@ false - Qt::Horizontal + Qt::Orientation::Horizontal - QSlider::TicksBothSides + QSlider::TickPosition::TicksBothSides 10 @@ -316,7 +316,7 @@ Maximum Actors (5..40) - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter @@ -340,10 +340,10 @@ false - Qt::Horizontal + Qt::Orientation::Horizontal - QSlider::TicksBothSides + QSlider::TickPosition::TicksBothSides 5 @@ -402,6 +402,61 @@ + + + + Transition Type + + + + + + + Sets the transition effect to be used in game. + + + Idle - Broken + + + + + + + Idle - Broken + + + + + No Animation + + + + + Dissolve + + + + + Mosaic + + + + + Wipe Down + + + + + Windows + + + + + Unknown - Broken + + + + @@ -417,7 +472,7 @@ - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter false @@ -453,7 +508,7 @@ Direct 3D Devices - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter @@ -475,13 +530,13 @@ - QAbstractItemView::NoEditTriggers + QAbstractItemView::EditTrigger::NoEditTriggers true - QAbstractItemView::SelectRows + QAbstractItemView::SelectionBehavior::SelectRows diff --git a/ISLE/emscripten/emscripten.patch b/ISLE/emscripten/emscripten.patch index 899d72eb..0bc8222d 100644 --- a/ISLE/emscripten/emscripten.patch +++ b/ISLE/emscripten/emscripten.patch @@ -139,3 +139,21 @@ index e8c9f7e21..caf1971d2 100644 }, - }); +diff --git a/src/preamble.js b/src/preamble.js +index 572694517..0d2f4421b 100644 +--- a/src/preamble.js ++++ b/src/preamble.js +@@ -1062,3 +1062,13 @@ function getCompilerSetting(name) { + // dynamic linker as symbols are loaded. + var asyncifyStubs = {}; + #endif ++ ++(async () => { ++ try { ++ await navigator.storage.getDirectory(); ++ Module["disableOpfs"] = false; ++ } catch (e) { ++ Module["disableOpfs"] = true; ++ } ++})(); ++ diff --git a/ISLE/emscripten/filesystem.cpp b/ISLE/emscripten/filesystem.cpp index 395242a1..50cd9012 100644 --- a/ISLE/emscripten/filesystem.cpp +++ b/ISLE/emscripten/filesystem.cpp @@ -6,6 +6,7 @@ #include #include +#include #include static backend_t opfs = nullptr; @@ -13,10 +14,16 @@ static backend_t fetchfs = nullptr; extern const char* g_files[46]; -void Emscripten_SetupConfig(const char* p_iniConfig) +bool Emscripten_OPFSDisabled() { - if (!p_iniConfig || !*p_iniConfig) { - return; + return MAIN_THREAD_EM_ASM_INT({return !!Module["disableOpfs"]}); +} + +bool Emscripten_SetupConfig(const char* p_iniConfig) +{ + if (Emscripten_OPFSDisabled()) { + SDL_Log("OPFS is disabled; ignoring .ini path"); + return false; } opfs = wasmfs_create_opfs_backend(); @@ -28,6 +35,8 @@ void Emscripten_SetupConfig(const char* p_iniConfig) wasmfs_create_directory(iniConfig.GetData(), 0644, opfs); *parse = '/'; } + + return true; } void Emscripten_SetupFilesystem() @@ -66,7 +75,7 @@ void Emscripten_SetupFilesystem() registerFile(file); } - if (GameState()->GetSavePath() && *GameState()->GetSavePath()) { + if (GameState()->GetSavePath() && *GameState()->GetSavePath() && !Emscripten_OPFSDisabled()) { if (!opfs) { opfs = wasmfs_create_opfs_backend(); } diff --git a/ISLE/emscripten/filesystem.h b/ISLE/emscripten/filesystem.h index 131df1c8..ad78a349 100644 --- a/ISLE/emscripten/filesystem.h +++ b/ISLE/emscripten/filesystem.h @@ -10,7 +10,7 @@ inline static const char* Emscripten_savePath = "/save"; inline static const char* Emscripten_streamPath = "/"; inline static const char* Emscripten_streamHost = ISLE_EMSCRIPTEN_HOST; -void Emscripten_SetupConfig(const char* p_iniConfig); +bool Emscripten_SetupConfig(const char* p_iniConfig); void Emscripten_SetupFilesystem(); #endif // EMSCRIPTEN_FILESYSTEM_H diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 9c7430c7..b30a43ce 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -475,7 +475,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) SDL_Keycode keyCode = event->key.key; - if (event->key.mod == SDL_KMOD_LALT && keyCode == SDLK_RETURN) { + if ((event->key.mod & SDL_KMOD_LALT) && keyCode == SDLK_RETURN) { SDL_SetWindowFullscreen(window, !(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN)); } else { @@ -859,6 +859,13 @@ bool IsleApp::LoadConfig() { char* prefPath = SDL_GetPrefPath("isledecomp", "isle"); char* iniConfig; + +#ifdef __EMSCRIPTEN__ + if (m_iniPath && !Emscripten_SetupConfig(m_iniPath)) { + m_iniPath = NULL; + } +#endif + if (m_iniPath) { iniConfig = new char[strlen(m_iniPath) + 1]; strcpy(iniConfig, m_iniPath); @@ -874,10 +881,6 @@ bool IsleApp::LoadConfig() } SDL_Log("Reading configuration from \"%s\"", iniConfig); -#ifdef __EMSCRIPTEN__ - Emscripten_SetupConfig(iniConfig); -#endif - dictionary* dict = iniparser_load(iniConfig); // [library:config] diff --git a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp index 8c2c994d..6fd211c6 100644 --- a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp @@ -400,47 +400,18 @@ void MxTransitionManager::WipeDownTransition() return; } - DDSURFACEDESC ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); + RECT fillRect = g_fullScreenRect; + // For each of the 240 animation ticks, blank out two scanlines + // starting at the top of the screen. + fillRect.bottom = 2 * (m_animationTimer + 1); - HRESULT res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - if (res == DDERR_SURFACELOST) { - m_ddSurface->Restore(); - res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - } + DDBLTFX bltFx = {}; + bltFx.dwSize = sizeof(bltFx); + bltFx.dwFillColor = 0xFF000000; - if (res == DD_OK) { - SubmitCopyRect(&ddsd); + m_ddSurface->Blt(&fillRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - // For each of the 240 animation ticks, blank out two scanlines - // starting at the top of the screen. - MxU8* line = (MxU8*) ddsd.lpSurface + 2 * ddsd.lPitch * m_animationTimer; - - if (ddsd.ddpfPixelFormat.dwRGBBitCount == 32) { - MxU32* pixels = (MxU32*) line; - int pixelsPerLine = ddsd.lPitch / 4; - for (int i = 0; i < pixelsPerLine; i++) { - pixels[i] = 0xFF000000; - } - line += ddsd.lPitch; - pixels = (MxU32*) line; - for (int i = 0; i < pixelsPerLine; i++) { - pixels[i] = 0xFF000000; - } - } - else { - memset(line, 0, ddsd.lPitch); - - line += ddsd.lPitch; - memset(line, 0, ddsd.lPitch); - } - - SetupCopyRect(&ddsd); - m_ddSurface->Unlock(ddsd.lpSurface); - - m_animationTimer++; - } + m_animationTimer++; } // FUNCTION: LEGO1 0x1004c270 @@ -452,65 +423,28 @@ void MxTransitionManager::WindowsTransition() return; } - DDSURFACEDESC ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); + DDBLTFX bltFx = {}; + bltFx.dwSize = sizeof(bltFx); + bltFx.dwFillColor = 0xFF000000; - HRESULT res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - if (res == DDERR_SURFACELOST) { - m_ddSurface->Restore(); - res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - } + int top = m_animationTimer; + int bottom = 480 - m_animationTimer - 1; + int left = m_animationTimer; + int right = 639 - m_animationTimer; - if (res == DD_OK) { - SubmitCopyRect(&ddsd); + RECT topRect = {0, top, 640, top + 1}; + m_ddSurface->Blt(&topRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - MxU8* line = (MxU8*) ddsd.lpSurface + m_animationTimer * ddsd.lPitch; + RECT bottomRect = {0, bottom, 640, bottom + 1}; + m_ddSurface->Blt(&bottomRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - MxS32 bytesPerPixel = ddsd.ddpfPixelFormat.dwRGBBitCount / 8; + RECT leftRect = {left, top + 1, left + 1, bottom}; + m_ddSurface->Blt(&leftRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - if (bytesPerPixel == 4) { - MxU32* pixels = (MxU32*) line; - for (int i = 0; i < 640; i++) { - pixels[i] = 0xFF000000; - } + RECT rightRect = {right, top + 1, right + 1, bottom}; + m_ddSurface->Blt(&rightRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - for (MxS32 i = m_animationTimer + 1; i < 480 - m_animationTimer - 1; i++) { - line += ddsd.lPitch; - pixels = (MxU32*) line; - pixels[m_animationTimer] = 0xFF000000; - pixels[639 - m_animationTimer] = 0xFF000000; - } - - if (m_animationTimer < 240 - 1) { - line += ddsd.lPitch; - pixels = (MxU32*) line; - for (int i = 0; i < 640; i++) { - pixels[i] = 0xFF000000; - } - } - } - else { - memset(line, 0, 640 * bytesPerPixel); - - for (MxS32 i = m_animationTimer + 1; i < 480 - m_animationTimer - 1; i++) { - line += ddsd.lPitch; - - memset(line + m_animationTimer * bytesPerPixel, 0, bytesPerPixel); - memset(line + (639 - m_animationTimer) * bytesPerPixel, 0, bytesPerPixel); - } - - if (m_animationTimer < 240 - 1) { - line += ddsd.lPitch; - memset(line, 0, 640 * bytesPerPixel); - } - } - - SetupCopyRect(&ddsd); - m_ddSurface->Unlock(ddsd.lpSurface); - - m_animationTimer++; - } + m_animationTimer++; } // FUNCTION: LEGO1 0x1004c3e0 diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index 8b92065c..cdb20197 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -387,15 +387,7 @@ inline void LegoVideoManager::DrawCursor() LPDIRECTDRAWSURFACE ddSurface2 = m_displaySurface->GetDirectDrawSurface2(); if (!m_cursorSurface) { - m_cursorRect.top = 0; - m_cursorRect.left = 0; - m_cursorRect.bottom = 16; - m_cursorRect.right = 16; - m_cursorSurface = MxDisplaySurface::CreateCursorSurface(); - - if (!m_cursorSurface) { - m_drawCursor = FALSE; - } + return; } ddSurface2 diff --git a/LEGO1/lego/sources/misc/legocontainer.cpp b/LEGO1/lego/sources/misc/legocontainer.cpp index 98836d6a..693f9b27 100644 --- a/LEGO1/lego/sources/misc/legocontainer.cpp +++ b/LEGO1/lego/sources/misc/legocontainer.cpp @@ -22,10 +22,9 @@ LegoTextureInfo* LegoTextureContainer::GetCached(LegoTextureInfo* p_textureInfo) memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); - if (p_textureInfo->m_surface->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL) == DD_OK) { + if (p_textureInfo->m_surface->GetSurfaceDesc(&desc) == DD_OK) { width = desc.dwWidth; height = desc.dwHeight; - p_textureInfo->m_surface->Unlock(desc.lpSurface); } for (LegoCachedTextureList::iterator it = m_cached.begin(); it != m_cached.end(); it++) { @@ -35,15 +34,8 @@ LegoTextureInfo* LegoTextureContainer::GetCached(LegoTextureInfo* p_textureInfo) memset(&newDesc, 0, sizeof(newDesc)); newDesc.dwSize = sizeof(newDesc); - if (surface->Lock(NULL, &newDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL) == DD_OK) { - BOOL und = FALSE; + if (surface->GetSurfaceDesc(&newDesc) == DD_OK) { if (newDesc.dwWidth == width && newDesc.dwHeight == height) { - und = TRUE; - } - - surface->Unlock(newDesc.lpSurface); - - if (und) { (*it).second = TRUE; (*it).first->m_texture->AddRef(); return (*it).first; diff --git a/LEGO1/mxdirectx/mxdirect3d.cpp b/LEGO1/mxdirectx/mxdirect3d.cpp index e338046f..0dae36e1 100644 --- a/LEGO1/mxdirectx/mxdirect3d.cpp +++ b/LEGO1/mxdirectx/mxdirect3d.cpp @@ -172,7 +172,7 @@ BOOL MxDirect3D::D3DSetMode() DDBLTFX ddBltFx = {}; ddBltFx.dwSize = sizeof(DDBLTFX); - ddBltFx.dwFillColor = 0; + ddBltFx.dwFillColor = 0xFF000000; if (backBuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx) != DD_OK) { SDL_Log("MxDirect3D::D3DSetMode() color fill failed\n"); diff --git a/LEGO1/mxdirectx/mxdirectdraw.cpp b/LEGO1/mxdirectx/mxdirectdraw.cpp index bedf4d2e..7ccb78c2 100644 --- a/LEGO1/mxdirectx/mxdirectdraw.cpp +++ b/LEGO1/mxdirectx/mxdirectdraw.cpp @@ -519,35 +519,23 @@ BOOL MxDirectDraw::DDCreateSurfaces() void MxDirectDraw::ClearBackBuffers() { HRESULT result; - byte* line; - DDSURFACEDESC ddsd; + DDBLTFX ddbltfx = {}; + ddbltfx.dwSize = sizeof(DDBLTFX); + ddbltfx.dwFillColor = 0xFF000000; int count = m_bFlipSurfaces ? 2 : 1; - int value = 0; for (int i = 0; i < count; i++) { - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - result = m_pBackBuffer->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); + result = m_pBackBuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); if (result == DDERR_SURFACELOST) { m_pBackBuffer->Restore(); - result = m_pBackBuffer->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); + result = m_pBackBuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); } if (result != DD_OK) { - // lock failed + // blt failed return; } - // clear backBuffer - line = (byte*) ddsd.lpSurface; - for (int j = ddsd.dwHeight; j--;) { - memset(line, value, ddsd.dwWidth); - line += ddsd.lPitch; - } - - m_pBackBuffer->Unlock(ddsd.lpSurface); - if (m_bFlipSurfaces) { m_pFrontBuffer->Flip(NULL, DDFLIP_WAIT); } diff --git a/LEGO1/omni/include/mxdisplaysurface.h b/LEGO1/omni/include/mxdisplaysurface.h index ec9c6aa5..3a3dcd08 100644 --- a/LEGO1/omni/include/mxdisplaysurface.h +++ b/LEGO1/omni/include/mxdisplaysurface.h @@ -71,14 +71,6 @@ class MxDisplaySurface : public MxCore { MxS32 p_height, MxBool p_RLE ); // vtable+0x30 - virtual void VTable0x34( - MxU8* p_pixels, - MxS32 p_bpp, - MxS32 p_width, - MxS32 p_height, - MxS32 p_x, - MxS32 p_y - ); // vtable+0x34 virtual void Display( MxS32 p_left, MxS32 p_top, @@ -97,7 +89,6 @@ class MxDisplaySurface : public MxCore { ); // vtable+0x44 void ClearScreen(); - static LPDIRECTDRAWSURFACE CreateCursorSurface(); static LPDIRECTDRAWSURFACE CreateCursorSurface(const CursorBitmap* p_cursorBitmap); static LPDIRECTDRAWSURFACE CopySurface(LPDIRECTDRAWSURFACE p_src); diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index 4382ad53..b10330f2 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -72,7 +72,7 @@ void MxDisplaySurface::ClearScreen() DDBLTFX ddBltFx = {}; ddBltFx.dwSize = sizeof(DDBLTFX); - ddBltFx.dwFillColor = 0; + ddBltFx.dwFillColor = 0xFF000000; for (MxS32 i = 0; i < backBuffers; i++) { if (m_ddSurface2->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddBltFx) == DDERR_SURFACELOST) { @@ -716,61 +716,6 @@ void MxDisplaySurface::DrawTransparentRLE( } } -// FUNCTION: LEGO1 0x100bb850 -// FUNCTION: BETA10 0x10141191 -void MxDisplaySurface::VTable0x34(MxU8* p_pixels, MxS32 p_bpp, MxS32 p_width, MxS32 p_height, MxS32 p_x, MxS32 p_y) -{ - DDSURFACEDESC surfaceDesc; - memset(&surfaceDesc, 0, sizeof(surfaceDesc)); - surfaceDesc.dwSize = sizeof(surfaceDesc); - - HRESULT result = m_ddSurface2->Lock(NULL, &surfaceDesc, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - - if (result == DDERR_SURFACELOST) { - m_ddSurface2->Restore(); - result = m_ddSurface2->Lock(NULL, &surfaceDesc, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - } - - if (result == DD_OK) { - MxU8* pixels = p_pixels; - MxS32 bytesPerPixel = m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount / 8; - if (p_bpp != 8 && bytesPerPixel != p_bpp) { - MxTrace("Source format to display format NOT_IMPLEMENTED"); - assert(0); - return; - } - - MxU8* dst = (MxU8*) surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + bytesPerPixel * p_x; - MxLong stride = p_width * bytesPerPixel; - MxLong length = -bytesPerPixel * p_width + surfaceDesc.lPitch; - - if (bytesPerPixel == p_bpp) { - while (p_height--) { - memcpy(dst, pixels, p_width * bytesPerPixel); - pixels += stride; - dst += length; - } - } - else { - for (MxS32 i = 0; i < p_height; i++) { - for (MxS32 j = 0; j < p_width; j++) { - if (bytesPerPixel == 2) { - *(MxU16*) dst = m_16bitPal[*pixels++]; - } - else { - *(MxU32*) dst = m_32bitPal[*pixels++]; - } - dst += bytesPerPixel; - } - pixels += stride; - dst += length; - } - } - - m_ddSurface2->Unlock(surfaceDesc.lpSurface); - } -} - // FUNCTION: LEGO1 0x100bba50 void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p_top2, MxS32 p_width, MxS32 p_height) { @@ -779,21 +724,11 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p if (g_unk0x1010215c < 2) { g_unk0x1010215c++; - DDSURFACEDESC ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - if (m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL) == DD_OK) { - MxU8* surface = (MxU8*) ddsd.lpSurface; - MxS32 height = m_videoParam.GetRect().GetHeight(); + DDBLTFX ddbltfx = {}; + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = 0xFF000000; - for (MxU32 i = 0; i < ddsd.dwHeight; i++) { - memset(surface, 0, ddsd.lPitch); - surface += ddsd.lPitch; - } - - m_ddSurface2->Unlock(ddsd.lpSurface); - } - else { + if (m_ddSurface2->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx) != DD_OK) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDisplaySurface::Display error\n"); } } @@ -812,7 +747,7 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p DDBLTFX data; memset(&data, 0, sizeof(data)); data.dwSize = sizeof(data); - data.dwDDFX = 8; + data.dwDDFX = DDBLTFX_NOTEARING; if (m_ddSurface1->Blt((LPRECT) &b, m_ddSurface2, (LPRECT) &a, DDBLT_NONE, &data) == DDERR_SURFACELOST) { m_ddSurface1->Restore(); @@ -1015,82 +950,6 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::CopySurface(LPDIRECTDRAWSURFACE p_src) return newSurface; } -// FUNCTION: LEGO1 0x100bc070 -LPDIRECTDRAWSURFACE MxDisplaySurface::CreateCursorSurface() -{ - LPDIRECTDRAWSURFACE newSurface = NULL; - IDirectDraw* draw = MVideoManager()->GetDirectDraw(); - MVideoManager(); - - DDSURFACEDESC ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - if (draw->GetDisplayMode(&ddsd) != DD_OK) { - return NULL; - } - - ddsd.dwWidth = 16; - ddsd.dwHeight = 16; - ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN; - - if (draw->CreateSurface(&ddsd, &newSurface, NULL) != DD_OK) { - ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; - ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - - if (draw->CreateSurface(&ddsd, &newSurface, NULL) != DD_OK) { - goto done; - } - } - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - if (newSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL) != DD_OK) { - goto done; - } - else { - MxU16* surface = (MxU16*) ddsd.lpSurface; - MxLong pitch = ddsd.lPitch; - - // draw a simple cursor to the surface - for (MxS32 x = 0; x < 16; x++) { - MxU16* surface2 = surface; - for (MxS32 y = 0; y < 16; y++) { - if ((y > 10 || x) && (x > 10 || y) && x + y != 10) { - if (x + y > 10) { - *surface2 = RGB555_CREATE(0x1f, 0, 0x1f); - } - else { - *surface2 = -1; - } - } - else { - *surface2 = 0; - } - surface2++; - } - surface = (MxU16*) ((MxU8*) surface + pitch); - } - - newSurface->Unlock(ddsd.lpSurface); - DDCOLORKEY colorkey; - colorkey.dwColorSpaceHighValue = RGB555_CREATE(0x1f, 0, 0x1f); - colorkey.dwColorSpaceLowValue = RGB555_CREATE(0x1f, 0, 0x1f); - newSurface->SetColorKey(DDCKEY_SRCBLT, &colorkey); - - return newSurface; - } - -done: - if (newSurface) { - newSurface->Release(); - } - - return NULL; -} - // FUNCTION: LEGO1 0x100bc200 void MxDisplaySurface::VTable0x24( LPDDSURFACEDESC p_desc, diff --git a/miniwin/include/miniwin/ddraw.h b/miniwin/include/miniwin/ddraw.h index 1e3fd17f..2a8932a2 100644 --- a/miniwin/include/miniwin/ddraw.h +++ b/miniwin/include/miniwin/ddraw.h @@ -246,9 +246,13 @@ struct DDSCAPS { }; typedef struct DDSCAPS* LPDDSCAPS; +#define DDBLTFX_NOTEARING DDBLTFXFlags::NOTEARING +enum class DDBLTFXFlags : uint8_t { + NOTEARING = 1 << 3, +}; struct DDBLTFX { DWORD dwSize; - DWORD dwDDFX; + DDBLTFXFlags dwDDFX; DWORD dwROP; DWORD dwFillColor; }; diff --git a/miniwin/src/d3drm/backends/citro3d/renderer.cpp b/miniwin/src/d3drm/backends/citro3d/renderer.cpp index f076cf70..f71f9255 100644 --- a/miniwin/src/d3drm/backends/citro3d/renderer.cpp +++ b/miniwin/src/d3drm/backends/citro3d/renderer.cpp @@ -443,6 +443,32 @@ void ConvertMatrix(const D3DRMMATRIX4D in, C3D_Mtx* out) } } +void SetMaterialAppearance( + const FColor& color, + float shininess, + int uLoc_meshColor, + int uLoc_shininess, + C3D_Tex* textures +) +{ + C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_meshColor, color.r, color.g, color.b, color.a); + C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_shininess, shininess, 0.0f, 0.0f, 0.0f); + + C3D_TexEnv* env = C3D_GetTexEnv(0); + C3D_TexEnvInit(env); + + if (textures) { + C3D_TexBind(0, textures); + C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); + C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); + } + else { + C3D_TexBind(0, nullptr); + C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); + C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); + } +} + void Citro3DRenderer::SubmitDraw( DWORD meshId, const D3DRMMATRIX4D& modelViewMatrix, @@ -462,32 +488,17 @@ void Citro3DRenderer::SubmitDraw( BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, mesh.vbo, sizeof(D3DRMVERTEX), 3, 0x210); - C3D_FVUnifSet( - GPU_VERTEX_SHADER, + SetMaterialAppearance( + {appearance.color.r / 255.0f, + appearance.color.g / 255.0f, + appearance.color.b / 255.0f, + appearance.color.a / 255.0f}, + appearance.shininess, uLoc_meshColor, - appearance.color.r / 255.0f, - appearance.color.g / 255.0f, - appearance.color.b / 255.0f, - appearance.color.a / 255.0f + uLoc_shininess, + appearance.textureId != NO_TEXTURE_ID ? &m_textures[appearance.textureId].c3dTex : nullptr ); - C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_shininess, appearance.shininess / 255.0f, 0.0f, 0.0f, 0.0f); - - if (appearance.textureId != NO_TEXTURE_ID) { - C3D_TexBind(0, &m_textures[appearance.textureId].c3dTex); - C3D_TexEnv* env = C3D_GetTexEnv(0); - C3D_TexEnvInit(env); - C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); - } - else { - C3D_TexBind(0, nullptr); - C3D_TexEnv* env = C3D_GetTexEnv(0); - C3D_TexEnvInit(env); - C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); - } - C3D_DrawArrays(GPU_TRIANGLES, 0, mesh.vertexCount); } @@ -519,7 +530,7 @@ void Citro3DRenderer::Flip() g_rendering = false; } -void Citro3DRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void Citro3DRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { C3D_AlphaBlend(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); StartFrame(); @@ -545,16 +556,9 @@ void Citro3DRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightClr + 1, 0.0f, 0.0f, 0.0f, 0.0f); C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightClr + 2, 1.0f, 1.0f, 1.0f, 1.0f); // Ambient - C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_shininess, 0.0f, 0.0f, 0.0f, 0.0f); - C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_meshColor, 1.0f, 1.0f, 1.0f, 1.0f); + C3DTextureCacheEntry* texture = (textureId != NO_TEXTURE_ID) ? &m_textures[textureId] : nullptr; - C3DTextureCacheEntry& texture = m_textures[textureId]; - - C3D_TexBind(0, &texture.c3dTex); - C3D_TexEnv* env = C3D_GetTexEnv(0); - C3D_TexEnvInit(env); - C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); + SetMaterialAppearance(color, 0.0f, uLoc_meshColor, uLoc_shininess, texture ? &texture->c3dTex : nullptr); float scale = m_viewportTransform.scale; @@ -563,10 +567,17 @@ void Citro3DRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con float x2 = x1 + static_cast(dstRect.w); float y2 = y1 + static_cast(dstRect.h); - float u0 = (srcRect.x * scale) / texture.width; - float u1 = ((srcRect.x + srcRect.w) * scale) / texture.width; - float v0 = (srcRect.y * scale) / texture.height; - float v1 = ((srcRect.y + srcRect.h) * scale) / texture.height; + float u0 = 0.0f; + float u1 = 0.0f; + float v0 = 0.0f; + float v1 = 0.0f; + + if (texture) { + u0 = (srcRect.x * scale) / texture->width; + u1 = ((srcRect.x + srcRect.w) * scale) / texture->width; + v0 = (srcRect.y * scale) / texture->height; + v1 = ((srcRect.y + srcRect.h) * scale) / texture->height; + } C3D_ImmDrawBegin(GPU_TRIANGLES); diff --git a/miniwin/src/d3drm/backends/directx9/actual.cpp b/miniwin/src/d3drm/backends/directx9/actual.cpp index 33dc2864..4ccea210 100644 --- a/miniwin/src/d3drm/backends/directx9/actual.cpp +++ b/miniwin/src/d3drm/backends/directx9/actual.cpp @@ -297,44 +297,23 @@ D3DMATRIX ToD3DMATRIX(const Matrix4x4& in) return out; } -void Actual_SubmitDraw( - const D3D9MeshCacheEntry* mesh, - const Matrix4x4* modelViewMatrix, - const Matrix4x4* worldMatrix, - const Matrix4x4* viewMatrix, - const Matrix3x3* normalMatrix, - const Appearance* appearance, - IDirect3DTexture9* texture -) +void SetMaterialAndTexture(const FColor& color, float shininess, IDirect3DTexture9* texture) { - D3DMATRIX proj = ToD3DMATRIX(g_projection); - g_device->SetTransform(D3DTS_PROJECTION, &proj); - D3DMATRIX view = ToD3DMATRIX(*viewMatrix); - g_device->SetTransform(D3DTS_VIEW, &view); - D3DMATRIX world = ToD3DMATRIX(*worldMatrix); - g_device->SetTransform(D3DTS_WORLD, &world); - D3DMATERIAL9 mat = {}; - mat.Diffuse.r = appearance->color.r / 255.0f; - mat.Diffuse.g = appearance->color.g / 255.0f; - mat.Diffuse.b = appearance->color.b / 255.0f; - mat.Diffuse.a = appearance->color.a / 255.0f; + mat.Diffuse.r = color.r / 255.0f; + mat.Diffuse.g = color.g / 255.0f; + mat.Diffuse.b = color.b / 255.0f; + mat.Diffuse.a = color.a / 255.0f; mat.Ambient = mat.Diffuse; - if (appearance->shininess != 0) { + if (shininess != 0) { g_device->SetRenderState(D3DRS_SPECULARENABLE, TRUE); - mat.Specular.r = 1.0f; - mat.Specular.g = 1.0f; - mat.Specular.b = 1.0f; - mat.Specular.a = 1.0f; - mat.Power = appearance->shininess; + mat.Specular = {1.0f, 1.0f, 1.0f, 1.0f}; + mat.Power = shininess; } else { g_device->SetRenderState(D3DRS_SPECULARENABLE, FALSE); - mat.Specular.r = 0.0f; - mat.Specular.g = 0.0f; - mat.Specular.b = 0.0f; - mat.Specular.a = 0.0f; + mat.Specular = {0.0f, 0.0f, 0.0f, 0.0f}; mat.Power = 0.0f; } @@ -352,6 +331,33 @@ void Actual_SubmitDraw( else { g_device->SetTexture(0, nullptr); } +} + +void Actual_SubmitDraw( + const D3D9MeshCacheEntry* mesh, + const Matrix4x4* modelViewMatrix, + const Matrix4x4* worldMatrix, + const Matrix4x4* viewMatrix, + const Matrix3x3* normalMatrix, + const Appearance* appearance, + IDirect3DTexture9* texture +) +{ + D3DMATRIX proj = ToD3DMATRIX(g_projection); + g_device->SetTransform(D3DTS_PROJECTION, &proj); + D3DMATRIX view = ToD3DMATRIX(*viewMatrix); + g_device->SetTransform(D3DTS_VIEW, &view); + D3DMATRIX world = ToD3DMATRIX(*worldMatrix); + g_device->SetTransform(D3DTS_WORLD, &world); + + SetMaterialAndTexture( + {appearance->color.r / 255.0f, + appearance->color.g / 255.0f, + appearance->color.b / 255.0f, + appearance->color.a / 255.0f}, + appearance->shininess, + texture + ); g_device->SetRenderState(D3DRS_SHADEMODE, mesh->flat ? D3DSHADE_FLAT : D3DSHADE_GOURAUD); @@ -367,7 +373,7 @@ uint32_t Actual_Flip() return g_device->Present(nullptr, nullptr, nullptr, nullptr); } -void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { StartScene(); @@ -405,10 +411,7 @@ void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, con g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - g_device->SetTexture(0, texture); - g_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - g_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - g_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetMaterialAndTexture(color, 0, texture); D3DSURFACE_DESC texDesc; texture->GetLevelDesc(0, &texDesc); diff --git a/miniwin/src/d3drm/backends/directx9/actual.h b/miniwin/src/d3drm/backends/directx9/actual.h index e3369ec9..bf09cb00 100644 --- a/miniwin/src/d3drm/backends/directx9/actual.h +++ b/miniwin/src/d3drm/backends/directx9/actual.h @@ -78,5 +78,5 @@ void Actual_SubmitDraw( void Actual_Resize(int width, int height, const ViewportTransform& viewportTransform); void Actual_Clear(float r, float g, float b); uint32_t Actual_Flip(); -void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, const SDL_Rect& dstRect); +void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color); uint32_t Actual_Download(SDL_Surface* target); diff --git a/miniwin/src/d3drm/backends/directx9/renderer.cpp b/miniwin/src/d3drm/backends/directx9/renderer.cpp index 2701528b..5c8a2354 100644 --- a/miniwin/src/d3drm/backends/directx9/renderer.cpp +++ b/miniwin/src/d3drm/backends/directx9/renderer.cpp @@ -273,9 +273,9 @@ void DirectX9Renderer::Flip() Actual_Flip(); } -void DirectX9Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void DirectX9Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { - Actual_Draw2DImage(m_textures[textureId].dxTexture, srcRect, dstRect); + Actual_Draw2DImage(m_textures[textureId].dxTexture, srcRect, dstRect, color); } void DirectX9Renderer::SetDither(bool dither) diff --git a/miniwin/src/d3drm/backends/opengl1/actual.cpp b/miniwin/src/d3drm/backends/opengl1/actual.cpp index d75eb04e..b1a464d5 100644 --- a/miniwin/src/d3drm/backends/opengl1/actual.cpp +++ b/miniwin/src/d3drm/backends/opengl1/actual.cpp @@ -285,9 +285,10 @@ void GL11_Clear(float r, float g, float b) } void GL11_Draw2DImage( - GLTextureCacheEntry& cache, + const GLTextureCacheEntry* cache, const SDL_Rect& srcRect, const SDL_Rect& dstRect, + const FColor& color, float left, float right, float bottom, @@ -296,6 +297,7 @@ void GL11_Draw2DImage( { glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); + glShadeModel(GL_FLAT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -306,17 +308,28 @@ void GL11_Draw2DImage( glLoadIdentity(); glDisable(GL_LIGHTING); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glColor4f(color.r, color.g, color.b, color.a); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, cache.glTextureId); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + float u1 = 0; + float v1 = 0; + float u2 = 0; + float v2 = 0; - float u1 = srcRect.x / cache.width; - float v1 = srcRect.y / cache.height; - float u2 = (srcRect.x + srcRect.w) / cache.width; - float v2 = (srcRect.y + srcRect.h) / cache.height; + if (cache) { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, cache->glTextureId); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + u1 = srcRect.x / cache->width; + v1 = srcRect.y / cache->height; + u2 = (srcRect.x + srcRect.w) / cache->width; + v2 = (srcRect.y + srcRect.h) / cache->height; + } + else { + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } float x1 = (float) dstRect.x; float y1 = (float) dstRect.y; diff --git a/miniwin/src/d3drm/backends/opengl1/actual.h b/miniwin/src/d3drm/backends/opengl1/actual.h index 7a6a4432..9460119c 100644 --- a/miniwin/src/d3drm/backends/opengl1/actual.h +++ b/miniwin/src/d3drm/backends/opengl1/actual.h @@ -79,9 +79,10 @@ void GL11_SubmitDraw( void GL11_Resize(int width, int height); void GL11_Clear(float r, float g, float b); void GL11_Draw2DImage( - GLTextureCacheEntry& cache, + const GLTextureCacheEntry* cache, const SDL_Rect& srcRect, const SDL_Rect& dstRect, + const FColor& color, float left, float right, float bottom, diff --git a/miniwin/src/d3drm/backends/opengl1/renderer.cpp b/miniwin/src/d3drm/backends/opengl1/renderer.cpp index 4c6aacf9..8c43d14a 100644 --- a/miniwin/src/d3drm/backends/opengl1/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengl1/renderer.cpp @@ -372,7 +372,7 @@ void OpenGL1Renderer::Flip() } } -void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { m_dirty = true; @@ -381,7 +381,12 @@ void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con float top = -m_viewportTransform.offsetY / m_viewportTransform.scale; float bottom = (m_height - m_viewportTransform.offsetY) / m_viewportTransform.scale; - GL11_Draw2DImage(m_textures[textureId], srcRect, dstRect, left, right, bottom, top); + const GLTextureCacheEntry* texture = nullptr; + if (textureId != NO_TEXTURE_ID) { + texture = &m_textures[textureId]; + } + + GL11_Draw2DImage(texture, srcRect, dstRect, color, left, right, bottom, top); } void OpenGL1Renderer::SetDither(bool dither) diff --git a/miniwin/src/d3drm/backends/opengles2/renderer.cpp b/miniwin/src/d3drm/backends/opengles2/renderer.cpp index 28466bea..850e8b6e 100644 --- a/miniwin/src/d3drm/backends/opengles2/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengles2/renderer.cpp @@ -598,7 +598,7 @@ void OpenGLES2Renderer::Flip() } } -void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { m_dirty = true; @@ -607,25 +607,37 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c glUseProgram(m_shaderProgram); - float color[] = {1.0f, 1.0f, 1.0f, 1.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, color); + 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); - glUniform4f(m_colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); + glUniform4f(m_colorLoc, color.r, color.g, color.b, color.a); glUniform1f(m_shinLoc, 0.0f); - const GLES2TextureCacheEntry& texture = m_textures[textureId]; - float scaleX = static_cast(dstRect.w) / srcRect.w; - float scaleY = static_cast(dstRect.h) / srcRect.h; - SDL_Rect expandedDstRect = { - static_cast(std::round(dstRect.x - srcRect.x * scaleX)), - static_cast(std::round(dstRect.y - srcRect.y * scaleY)), - static_cast(std::round(texture.width * scaleX)), - static_cast(std::round(texture.height * scaleY)) - }; + SDL_Rect expandedDstRect; + if (textureId != NO_TEXTURE_ID) { + const GLES2TextureCacheEntry& texture = m_textures[textureId]; + float scaleX = static_cast(dstRect.w) / srcRect.w; + float scaleY = static_cast(dstRect.h) / srcRect.h; + expandedDstRect = { + static_cast(std::round(dstRect.x - srcRect.x * scaleX)), + static_cast(std::round(dstRect.y - srcRect.y * scaleY)), + static_cast(std::round(texture.width * scaleX)), + static_cast(std::round(texture.height * scaleY)) + }; + + glActiveTexture(GL_TEXTURE0); + glUniform1i(m_useTextureLoc, 1); + glBindTexture(GL_TEXTURE_2D, texture.glTextureId); + glUniform1i(m_textureLoc, 0); + } + else { + expandedDstRect = dstRect; + glUniform1i(m_useTextureLoc, 0); + } D3DRMMATRIX4D modelView, projection; Create2DTransformMatrix( @@ -645,11 +657,6 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glActiveTexture(GL_TEXTURE0); - glUniform1i(m_useTextureLoc, 1); - glBindTexture(GL_TEXTURE_2D, texture.glTextureId); - glUniform1i(m_textureLoc, 0); - glEnable(GL_SCISSOR_TEST); glScissor( static_cast(std::round(dstRect.x * m_viewportTransform.scale + m_viewportTransform.offsetX)), diff --git a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp index dff1cd2e..78d6c5a5 100644 --- a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp +++ b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp @@ -884,24 +884,37 @@ void Direct3DRMSDL3GPURenderer::Flip() m_cmdbuf = nullptr; } -void Direct3DRMSDL3GPURenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void Direct3DRMSDL3GPURenderer::Draw2DImage( + Uint32 textureId, + const SDL_Rect& srcRect, + const SDL_Rect& dstRect, + FColor color +) { if (!m_renderPass) { StartRenderPass(0, 0, 0, false); } SDL_BindGPUGraphicsPipeline(m_renderPass, m_uiPipeline); - const SDL3TextureCache& tex = m_textures[textureId]; - - auto surface = static_cast(tex.texture->m_surface); - float scaleX = static_cast(dstRect.w) / srcRect.w; - float scaleY = static_cast(dstRect.h) / srcRect.h; - SDL_Rect expandedDstRect = { - static_cast(std::round(dstRect.x - srcRect.x * scaleX)), - static_cast(std::round(dstRect.y - srcRect.y * scaleY)), - static_cast(std::round(static_cast(surface->m_surface->w) * scaleX)), - static_cast(std::round(static_cast(surface->m_surface->h) * scaleY)), - }; + SDL_GPUTexture* tex; + SDL_Rect expandedDstRect; + if (textureId == NO_TEXTURE_ID) { + expandedDstRect = dstRect; + tex = m_dummyTexture; + } + else { + SDL3TextureCache& cache = m_textures[textureId]; + tex = cache.gpuTexture; + auto surface = static_cast(cache.texture->m_surface); + float scaleX = static_cast(dstRect.w) / srcRect.w; + float scaleY = static_cast(dstRect.h) / srcRect.h; + expandedDstRect = { + static_cast(std::round(dstRect.x - srcRect.x * scaleX)), + static_cast(std::round(dstRect.y - srcRect.y * scaleY)), + static_cast(std::round(static_cast(surface->m_surface->w) * scaleX)), + static_cast(std::round(static_cast(surface->m_surface->h) * scaleY)), + }; + } Create2DTransformMatrix( expandedDstRect, @@ -916,11 +929,14 @@ void Direct3DRMSDL3GPURenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& sr SceneLight fullBright = {{1, 1, 1, 1}, {0, 0, 0}, 0, {0, 0, 0}, 0}; memcpy(&m_fragmentShadingData.lights, &fullBright, sizeof(SceneLight)); m_fragmentShadingData.lightCount = 1; - m_fragmentShadingData.color = {0xff, 0xff, 0xff, 0xff}; + m_fragmentShadingData.color.r = static_cast(color.r * 255); + m_fragmentShadingData.color.g = static_cast(color.g * 255); + m_fragmentShadingData.color.b = static_cast(color.b * 255); + m_fragmentShadingData.color.a = static_cast(color.a * 255); m_fragmentShadingData.shininess = 0.0f; m_fragmentShadingData.useTexture = 1; - SDL_GPUTextureSamplerBinding samplerBinding = {tex.gpuTexture, m_uiSampler}; + SDL_GPUTextureSamplerBinding samplerBinding = {tex, m_uiSampler}; SDL_BindGPUFragmentSamplers(m_renderPass, 0, &samplerBinding, 1); SDL_PushGPUVertexUniformData(m_cmdbuf, 0, &m_uniforms, sizeof(m_uniforms)); SDL_PushGPUFragmentUniformData(m_cmdbuf, 0, &m_fragmentShadingData, sizeof(m_fragmentShadingData)); diff --git a/miniwin/src/d3drm/backends/software/renderer.cpp b/miniwin/src/d3drm/backends/software/renderer.cpp index b4fab671..2ae8697e 100644 --- a/miniwin/src/d3drm/backends/software/renderer.cpp +++ b/miniwin/src/d3drm/backends/software/renderer.cpp @@ -774,16 +774,35 @@ void Direct3DRMSoftwareRenderer::Flip() SDL_RenderPresent(m_renderer); } -void Direct3DRMSoftwareRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void Direct3DRMSoftwareRenderer::Draw2DImage( + Uint32 textureId, + const SDL_Rect& srcRect, + const SDL_Rect& dstRect, + FColor color +) { - SDL_Surface* surface = m_textures[textureId].cached; - SDL_UnlockSurface(surface); SDL_Rect centeredRect = { static_cast(dstRect.x * m_viewportTransform.scale + m_viewportTransform.offsetX), static_cast(dstRect.y * m_viewportTransform.scale + m_viewportTransform.offsetY), static_cast(dstRect.w * m_viewportTransform.scale), static_cast(dstRect.h * m_viewportTransform.scale), }; + + if (textureId == NO_TEXTURE_ID) { + Uint32 sdlColor = SDL_MapRGBA( + m_format, + m_palette, + static_cast(color.r * 255), + static_cast(color.g * 255), + static_cast(color.b * 255), + static_cast(color.a * 255) + ); + SDL_FillSurfaceRect(m_renderedImage, ¢eredRect, sdlColor); + return; + } + + SDL_Surface* surface = m_textures[textureId].cached; + SDL_UnlockSurface(surface); SDL_BlitSurfaceScaled(surface, &srcRect, m_renderedImage, ¢eredRect, SDL_SCALEMODE_LINEAR); SDL_LockSurface(surface); } diff --git a/miniwin/src/ddraw/framebuffer.cpp b/miniwin/src/ddraw/framebuffer.cpp index 9f4224fd..20490b42 100644 --- a/miniwin/src/ddraw/framebuffer.cpp +++ b/miniwin/src/ddraw/framebuffer.cpp @@ -48,16 +48,32 @@ HRESULT FrameBufferImpl::Blt( if (!DDRenderer) { return DDERR_GENERIC; } + if (dynamic_cast(lpDDSrcSurface) == this) { return Flip(nullptr, DDFLIP_WAIT); } + if ((dwFlags & DDBLT_COLORFILL) == DDBLT_COLORFILL) { + Uint8 a = (lpDDBltFx->dwFillColor >> 24) & 0xFF; Uint8 r = (lpDDBltFx->dwFillColor >> 16) & 0xFF; Uint8 g = (lpDDBltFx->dwFillColor >> 8) & 0xFF; Uint8 b = lpDDBltFx->dwFillColor & 0xFF; - DDRenderer->Clear(r / 255.0f, g / 255.0f, b / 255.0f); + + float fa = a / 255.0f; + float fr = r / 255.0f; + float fg = g / 255.0f; + float fb = b / 255.0f; + + if (lpDestRect) { + SDL_Rect dstRect = ConvertRect(lpDestRect); + DDRenderer->Draw2DImage(NO_TEXTURE_ID, SDL_Rect{}, dstRect, {fr, fg, fb, fa}); + } + else { + DDRenderer->Clear(fr, fg, fb); + } return DD_OK; } + auto surface = static_cast(lpDDSrcSurface); if (!surface) { return DDERR_GENERIC; @@ -67,7 +83,7 @@ HRESULT FrameBufferImpl::Blt( lpSrcRect ? ConvertRect(lpSrcRect) : SDL_Rect{0, 0, surface->m_surface->w, surface->m_surface->h}; SDL_Rect dstRect = lpDestRect ? ConvertRect(lpDestRect) : SDL_Rect{0, 0, (int) m_virtualWidth, (int) m_virtualHeight}; - DDRenderer->Draw2DImage(textureId, srcRect, dstRect); + DDRenderer->Draw2DImage(textureId, srcRect, dstRect, {1.0f, 1.0f, 1.0f, 1.0f}); return DD_OK; } diff --git a/miniwin/src/internal/d3drmrenderer.h b/miniwin/src/internal/d3drmrenderer.h index a871bb26..d6464eb7 100644 --- a/miniwin/src/internal/d3drmrenderer.h +++ b/miniwin/src/internal/d3drmrenderer.h @@ -51,7 +51,7 @@ class Direct3DRMRenderer : public IDirect3DDevice2 { virtual void Resize(int width, int height, const ViewportTransform& viewportTransform) = 0; virtual void Clear(float r, float g, float b) = 0; virtual void Flip() = 0; - virtual void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) = 0; + virtual void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) = 0; virtual void Download(SDL_Surface* target) = 0; virtual void SetDither(bool dither) = 0; diff --git a/miniwin/src/internal/d3drmrenderer_citro3d.h b/miniwin/src/internal/d3drmrenderer_citro3d.h index af91b3dc..34863497 100644 --- a/miniwin/src/internal/d3drmrenderer_citro3d.h +++ b/miniwin/src/internal/d3drmrenderer_citro3d.h @@ -48,7 +48,7 @@ class Citro3DRenderer : public Direct3DRMRenderer { void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_directx9.h b/miniwin/src/internal/d3drmrenderer_directx9.h index 18ac126f..d1b0a581 100644 --- a/miniwin/src/internal/d3drmrenderer_directx9.h +++ b/miniwin/src/internal/d3drmrenderer_directx9.h @@ -34,7 +34,7 @@ class DirectX9Renderer : public Direct3DRMRenderer { void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_opengl1.h b/miniwin/src/internal/d3drmrenderer_opengl1.h index 656a964b..bd0fa003 100644 --- a/miniwin/src/internal/d3drmrenderer_opengl1.h +++ b/miniwin/src/internal/d3drmrenderer_opengl1.h @@ -34,7 +34,7 @@ class OpenGL1Renderer : public Direct3DRMRenderer { void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_opengles2.h b/miniwin/src/internal/d3drmrenderer_opengles2.h index 0aaec63d..7dbb1f4b 100644 --- a/miniwin/src/internal/d3drmrenderer_opengles2.h +++ b/miniwin/src/internal/d3drmrenderer_opengles2.h @@ -55,7 +55,7 @@ class OpenGLES2Renderer : public Direct3DRMRenderer { void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_sdl3gpu.h b/miniwin/src/internal/d3drmrenderer_sdl3gpu.h index cf68a8c4..b3afd674 100644 --- a/miniwin/src/internal/d3drmrenderer_sdl3gpu.h +++ b/miniwin/src/internal/d3drmrenderer_sdl3gpu.h @@ -65,7 +65,7 @@ class Direct3DRMSDL3GPURenderer : public Direct3DRMRenderer { void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_software.h b/miniwin/src/internal/d3drmrenderer_software.h index 91abac32..8b8c0dde 100644 --- a/miniwin/src/internal/d3drmrenderer_software.h +++ b/miniwin/src/internal/d3drmrenderer_software.h @@ -47,7 +47,7 @@ class Direct3DRMSoftwareRenderer : public Direct3DRMRenderer { void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override;