This commit is contained in:
Helloyunho 2025-07-04 14:59:56 +09:00
commit 6d9c255bff
35 changed files with 394 additions and 443 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -57,7 +57,7 @@
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
@ -129,10 +129,10 @@
<string>Save Path:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
<enum>Qt::TextFormat::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
@ -162,10 +162,10 @@
<string>Data Path:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
<enum>Qt::TextFormat::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
@ -241,7 +241,7 @@
<string>Maximum LOD</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
@ -262,10 +262,10 @@
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
<enum>QSlider::TickPosition::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>10</number>
@ -316,7 +316,7 @@
<string>Maximum Actors (5..40)</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
@ -340,10 +340,10 @@
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
<enum>QSlider::TickPosition::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>5</number>
@ -402,6 +402,61 @@
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Transition Type</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="transitionTypeComboBox">
<property name="toolTip">
<string>Sets the transition effect to be used in game.</string>
</property>
<property name="currentText">
<string>Idle - Broken</string>
</property>
<property name="placeholderText">
<string/>
</property>
<item>
<property name="text">
<string>Idle - Broken</string>
</property>
</item>
<item>
<property name="text">
<string>No Animation</string>
</property>
</item>
<item>
<property name="text">
<string>Dissolve</string>
</property>
</item>
<item>
<property name="text">
<string>Mosaic</string>
</property>
</item>
<item>
<property name="text">
<string>Wipe Down</string>
</property>
</item>
<item>
<property name="text">
<string>Windows</string>
</property>
</item>
<item>
<property name="text">
<string>Unknown - Broken</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QGroupBox" name="advancedGroup">
<property name="maximumSize">
@ -417,7 +472,7 @@
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="flat">
<bool>false</bool>
@ -453,7 +508,7 @@
<string>Direct 3D Devices</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
@ -475,13 +530,13 @@
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
</property>
</widget>
</item>

View File

@ -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;
+ }
+})();
+

View File

@ -6,6 +6,7 @@
#include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_log.h>
#include <emscripten.h>
#include <emscripten/wasmfs.h>
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();
}

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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");

View File

@ -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);
}

View File

@ -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);

View File

@ -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,

View File

@ -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;
};

View File

@ -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<float>(dstRect.w);
float y2 = y1 + static_cast<float>(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);

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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,

View File

@ -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)

View File

@ -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<float>(dstRect.w) / srcRect.w;
float scaleY = static_cast<float>(dstRect.h) / srcRect.h;
SDL_Rect expandedDstRect = {
static_cast<int>(std::round(dstRect.x - srcRect.x * scaleX)),
static_cast<int>(std::round(dstRect.y - srcRect.y * scaleY)),
static_cast<int>(std::round(texture.width * scaleX)),
static_cast<int>(std::round(texture.height * scaleY))
};
SDL_Rect expandedDstRect;
if (textureId != NO_TEXTURE_ID) {
const GLES2TextureCacheEntry& texture = m_textures[textureId];
float scaleX = static_cast<float>(dstRect.w) / srcRect.w;
float scaleY = static_cast<float>(dstRect.h) / srcRect.h;
expandedDstRect = {
static_cast<int>(std::round(dstRect.x - srcRect.x * scaleX)),
static_cast<int>(std::round(dstRect.y - srcRect.y * scaleY)),
static_cast<int>(std::round(texture.width * scaleX)),
static_cast<int>(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<int>(std::round(dstRect.x * m_viewportTransform.scale + m_viewportTransform.offsetX)),

View File

@ -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<DirectDrawSurfaceImpl*>(tex.texture->m_surface);
float scaleX = static_cast<float>(dstRect.w) / srcRect.w;
float scaleY = static_cast<float>(dstRect.h) / srcRect.h;
SDL_Rect expandedDstRect = {
static_cast<int>(std::round(dstRect.x - srcRect.x * scaleX)),
static_cast<int>(std::round(dstRect.y - srcRect.y * scaleY)),
static_cast<int>(std::round(static_cast<float>(surface->m_surface->w) * scaleX)),
static_cast<int>(std::round(static_cast<float>(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<DirectDrawSurfaceImpl*>(cache.texture->m_surface);
float scaleX = static_cast<float>(dstRect.w) / srcRect.w;
float scaleY = static_cast<float>(dstRect.h) / srcRect.h;
expandedDstRect = {
static_cast<int>(std::round(dstRect.x - srcRect.x * scaleX)),
static_cast<int>(std::round(dstRect.y - srcRect.y * scaleY)),
static_cast<int>(std::round(static_cast<float>(surface->m_surface->w) * scaleX)),
static_cast<int>(std::round(static_cast<float>(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<Uint8>(color.r * 255);
m_fragmentShadingData.color.g = static_cast<Uint8>(color.g * 255);
m_fragmentShadingData.color.b = static_cast<Uint8>(color.b * 255);
m_fragmentShadingData.color.a = static_cast<Uint8>(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));

View File

@ -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<int>(dstRect.x * m_viewportTransform.scale + m_viewportTransform.offsetX),
static_cast<int>(dstRect.y * m_viewportTransform.scale + m_viewportTransform.offsetY),
static_cast<int>(dstRect.w * m_viewportTransform.scale),
static_cast<int>(dstRect.h * m_viewportTransform.scale),
};
if (textureId == NO_TEXTURE_ID) {
Uint32 sdlColor = SDL_MapRGBA(
m_format,
m_palette,
static_cast<Uint8>(color.r * 255),
static_cast<Uint8>(color.g * 255),
static_cast<Uint8>(color.b * 255),
static_cast<Uint8>(color.a * 255)
);
SDL_FillSurfaceRect(m_renderedImage, &centeredRect, sdlColor);
return;
}
SDL_Surface* surface = m_textures[textureId].cached;
SDL_UnlockSurface(surface);
SDL_BlitSurfaceScaled(surface, &srcRect, m_renderedImage, &centeredRect, SDL_SCALEMODE_LINEAR);
SDL_LockSurface(surface);
}

View File

@ -48,16 +48,32 @@ HRESULT FrameBufferImpl::Blt(
if (!DDRenderer) {
return DDERR_GENERIC;
}
if (dynamic_cast<FrameBufferImpl*>(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<DirectDrawSurfaceImpl*>(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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;