mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-18 13:21:16 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
3c9c35538c
@ -492,6 +492,9 @@ if (ISLE_BUILD_APP)
|
|||||||
ISLE/res/isle.rc
|
ISLE/res/isle.rc
|
||||||
ISLE/isleapp.cpp
|
ISLE/isleapp.cpp
|
||||||
ISLE/islefiles.cpp
|
ISLE/islefiles.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/ISLE/res/arrow_bmp.h
|
||||||
|
${CMAKE_SOURCE_DIR}/ISLE/res/busy_bmp.h
|
||||||
|
${CMAKE_SOURCE_DIR}/ISLE/res/no_bmp.h
|
||||||
)
|
)
|
||||||
list(APPEND isle_targets isle)
|
list(APPEND isle_targets isle)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
@ -554,6 +557,39 @@ if (ISLE_BUILD_APP)
|
|||||||
ISLE/vita/messagebox.cpp
|
ISLE/vita/messagebox.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
if(Python3_FOUND)
|
||||||
|
if(NOT DEFINED PYTHON_PIL_AVAILABLE)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${Python3_EXECUTABLE} -c "import PIL; print('pil')"
|
||||||
|
RESULT_VARIABLE PIL_RESULT
|
||||||
|
OUTPUT_VARIABLE PIL_OUTPUT
|
||||||
|
ERROR_QUIET
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
if(PIL_RESULT EQUAL 0 AND PIL_OUTPUT STREQUAL "pil")
|
||||||
|
set(PIL_AVAILABLE 1)
|
||||||
|
else()
|
||||||
|
message(STATUS "Python PIL not found, using pre-generated headers.")
|
||||||
|
set(PIL_AVAILABLE 0)
|
||||||
|
endif()
|
||||||
|
set(PYTHON_PIL_AVAILABLE ${PIL_AVAILABLE} CACHE BOOL "Is Python3 Pillow available?")
|
||||||
|
endif()
|
||||||
|
if(PYTHON_PIL_AVAILABLE)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT
|
||||||
|
${CMAKE_SOURCE_DIR}/ISLE/res/arrow_bmp.h
|
||||||
|
${CMAKE_SOURCE_DIR}/ISLE/res/busy_bmp.h
|
||||||
|
${CMAKE_SOURCE_DIR}/ISLE/res/no_bmp.h
|
||||||
|
COMMAND ${Python3_EXECUTABLE} tools/curpng2h.py ISLE/res/arrow.png ISLE/res/busy.png ISLE/res/no.png
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
DEPENDS
|
||||||
|
${CMAKE_SOURCE_DIR}/tools/curpng2h.py
|
||||||
|
${CMAKE_SOURCE_DIR}/ISLE/res/arrow.png
|
||||||
|
${CMAKE_SOURCE_DIR}/ISLE/res/busy.png
|
||||||
|
${CMAKE_SOURCE_DIR}/ISLE/res/no.png
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ISLE_BUILD_CONFIG)
|
if (ISLE_BUILD_CONFIG)
|
||||||
|
|||||||
@ -59,6 +59,7 @@ CMainDialog::CMainDialog(QWidget* pParent) : QDialog(pParent)
|
|||||||
connect(m_ui->sound3DCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckbox3DSound);
|
connect(m_ui->sound3DCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckbox3DSound);
|
||||||
connect(m_ui->joystickCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxJoystick);
|
connect(m_ui->joystickCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxJoystick);
|
||||||
connect(m_ui->fullscreenCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxFullscreen);
|
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->okButton, &QPushButton::clicked, this, &CMainDialog::accept);
|
||||||
connect(m_ui->cancelButton, &QPushButton::clicked, this, &CMainDialog::reject);
|
connect(m_ui->cancelButton, &QPushButton::clicked, this, &CMainDialog::reject);
|
||||||
connect(m_ui->launchButton, &QPushButton::clicked, this, &CMainDialog::launch);
|
connect(m_ui->launchButton, &QPushButton::clicked, this, &CMainDialog::launch);
|
||||||
@ -212,6 +213,7 @@ void CMainDialog::UpdateInterface()
|
|||||||
m_ui->joystickCheckBox->setChecked(currentConfigApp->m_use_joystick);
|
m_ui->joystickCheckBox->setChecked(currentConfigApp->m_use_joystick);
|
||||||
m_ui->musicCheckBox->setChecked(currentConfigApp->m_music);
|
m_ui->musicCheckBox->setChecked(currentConfigApp->m_music);
|
||||||
m_ui->fullscreenCheckBox->setChecked(currentConfigApp->m_full_screen);
|
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->dataPath->setText(QString::fromStdString(currentConfigApp->m_cd_path));
|
||||||
m_ui->savePath->setText(QString::fromStdString(currentConfigApp->m_save_path));
|
m_ui->savePath->setText(QString::fromStdString(currentConfigApp->m_save_path));
|
||||||
}
|
}
|
||||||
@ -296,6 +298,13 @@ void CMainDialog::OnCheckboxFullscreen(bool checked)
|
|||||||
UpdateInterface();
|
UpdateInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMainDialog::TransitionTypeChanged(int index)
|
||||||
|
{
|
||||||
|
currentConfigApp->m_transition_type = index;
|
||||||
|
m_modified = true;
|
||||||
|
UpdateInterface();
|
||||||
|
}
|
||||||
|
|
||||||
void CMainDialog::SelectDataPathDialog()
|
void CMainDialog::SelectDataPathDialog()
|
||||||
{
|
{
|
||||||
QString data_path = QString::fromStdString(currentConfigApp->m_cd_path);
|
QString data_path = QString::fromStdString(currentConfigApp->m_cd_path);
|
||||||
|
|||||||
@ -43,6 +43,7 @@ private slots:
|
|||||||
void OnCheckboxJoystick(bool checked);
|
void OnCheckboxJoystick(bool checked);
|
||||||
void OnCheckboxMusic(bool checked);
|
void OnCheckboxMusic(bool checked);
|
||||||
void OnCheckboxFullscreen(bool checked);
|
void OnCheckboxFullscreen(bool checked);
|
||||||
|
void TransitionTypeChanged(int index);
|
||||||
void accept() override;
|
void accept() override;
|
||||||
void reject() override;
|
void reject() override;
|
||||||
void launch();
|
void launch();
|
||||||
|
|||||||
@ -70,6 +70,7 @@ bool CConfigApp::InitInstance()
|
|||||||
m_driver = NULL;
|
m_driver = NULL;
|
||||||
m_device = NULL;
|
m_device = NULL;
|
||||||
m_full_screen = TRUE;
|
m_full_screen = TRUE;
|
||||||
|
m_transition_type = 3; // 3: Mosaic
|
||||||
m_wide_view_angle = TRUE;
|
m_wide_view_angle = TRUE;
|
||||||
m_use_joystick = TRUE;
|
m_use_joystick = TRUE;
|
||||||
m_music = TRUE;
|
m_music = TRUE;
|
||||||
@ -153,6 +154,7 @@ bool CConfigApp::ReadRegisterSettings()
|
|||||||
m_display_bit_depth = iniparser_getint(dict, "isle:Display Bit Depth", -1);
|
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_flip_surfaces = iniparser_getboolean(dict, "isle:Flip Surfaces", m_flip_surfaces);
|
||||||
m_full_screen = iniparser_getboolean(dict, "isle:Full Screen", m_full_screen);
|
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_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_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);
|
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:Full Screen", m_full_screen);
|
||||||
SetIniBool(dict, "isle:Wide View Angle", m_wide_view_angle);
|
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:3DSound", m_3d_sound);
|
||||||
SetIniBool(dict, "isle:Music", m_music);
|
SetIniBool(dict, "isle:Music", m_music);
|
||||||
|
|
||||||
|
|||||||
@ -65,6 +65,7 @@ class CConfigApp {
|
|||||||
int m_display_bit_depth;
|
int m_display_bit_depth;
|
||||||
bool m_flip_surfaces;
|
bool m_flip_surfaces;
|
||||||
bool m_full_screen;
|
bool m_full_screen;
|
||||||
|
int m_transition_type;
|
||||||
bool m_3d_video_ram;
|
bool m_3d_video_ram;
|
||||||
bool m_wide_view_angle;
|
bool m_wide_view_angle;
|
||||||
bool m_3d_sound;
|
bool m_3d_sound;
|
||||||
|
|||||||
@ -57,7 +57,7 @@
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -129,10 +129,10 @@
|
|||||||
<string>Save Path:</string>
|
<string>Save Path:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textFormat">
|
<property name="textFormat">
|
||||||
<enum>Qt::PlainText</enum>
|
<enum>Qt::TextFormat::PlainText</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -162,10 +162,10 @@
|
|||||||
<string>Data Path:</string>
|
<string>Data Path:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textFormat">
|
<property name="textFormat">
|
||||||
<enum>Qt::PlainText</enum>
|
<enum>Qt::TextFormat::PlainText</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -241,7 +241,7 @@
|
|||||||
<string>Maximum LOD</string>
|
<string>Maximum LOD</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
<item>
|
<item>
|
||||||
@ -262,10 +262,10 @@
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="tickPosition">
|
<property name="tickPosition">
|
||||||
<enum>QSlider::TicksBothSides</enum>
|
<enum>QSlider::TickPosition::TicksBothSides</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="tickInterval">
|
<property name="tickInterval">
|
||||||
<number>10</number>
|
<number>10</number>
|
||||||
@ -316,7 +316,7 @@
|
|||||||
<string>Maximum Actors (5..40)</string>
|
<string>Maximum Actors (5..40)</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
<item>
|
<item>
|
||||||
@ -340,10 +340,10 @@
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="tickPosition">
|
<property name="tickPosition">
|
||||||
<enum>QSlider::TicksBothSides</enum>
|
<enum>QSlider::TickPosition::TicksBothSides</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="tickInterval">
|
<property name="tickInterval">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
@ -402,6 +402,66 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fake Mosaic</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="advancedGroup">
|
<widget class="QGroupBox" name="advancedGroup">
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
@ -417,7 +477,7 @@
|
|||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
@ -453,7 +513,7 @@
|
|||||||
<string>Direct 3D Devices</string>
|
<string>Direct 3D Devices</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -475,13 +535,13 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="editTriggers">
|
<property name="editTriggers">
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="alternatingRowColors">
|
<property name="alternatingRowColors">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="selectionBehavior">
|
<property name="selectionBehavior">
|
||||||
<enum>QAbstractItemView::SelectRows</enum>
|
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@ -18,5 +18,5 @@ void N3DS_SetupDefaultConfigOverrides(dictionary* p_dictionary)
|
|||||||
iniparser_set(p_dictionary, "isle:savepath", "sdmc:/3ds/isle");
|
iniparser_set(p_dictionary, "isle:savepath", "sdmc:/3ds/isle");
|
||||||
|
|
||||||
// Use e_noAnimation/cut transition
|
// Use e_noAnimation/cut transition
|
||||||
iniparser_set(p_dictionary, "isle:Transition Type", "1");
|
iniparser_set(p_dictionary, "isle:Transition Type", "7");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
+ }
|
||||||
|
+})();
|
||||||
|
+
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL_filesystem.h>
|
#include <SDL3/SDL_filesystem.h>
|
||||||
#include <SDL3/SDL_log.h>
|
#include <SDL3/SDL_log.h>
|
||||||
|
#include <emscripten.h>
|
||||||
#include <emscripten/wasmfs.h>
|
#include <emscripten/wasmfs.h>
|
||||||
|
|
||||||
static backend_t opfs = nullptr;
|
static backend_t opfs = nullptr;
|
||||||
@ -13,10 +14,16 @@ static backend_t fetchfs = nullptr;
|
|||||||
|
|
||||||
extern const char* g_files[46];
|
extern const char* g_files[46];
|
||||||
|
|
||||||
void Emscripten_SetupConfig(const char* p_iniConfig)
|
bool Emscripten_OPFSDisabled()
|
||||||
{
|
{
|
||||||
if (!p_iniConfig || !*p_iniConfig) {
|
return MAIN_THREAD_EM_ASM_INT({return !!Module["disableOpfs"]});
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
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();
|
opfs = wasmfs_create_opfs_backend();
|
||||||
@ -28,6 +35,8 @@ void Emscripten_SetupConfig(const char* p_iniConfig)
|
|||||||
wasmfs_create_directory(iniConfig.GetData(), 0644, opfs);
|
wasmfs_create_directory(iniConfig.GetData(), 0644, opfs);
|
||||||
*parse = '/';
|
*parse = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emscripten_SetupFilesystem()
|
void Emscripten_SetupFilesystem()
|
||||||
@ -66,7 +75,7 @@ void Emscripten_SetupFilesystem()
|
|||||||
registerFile(file);
|
registerFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameState()->GetSavePath() && *GameState()->GetSavePath()) {
|
if (GameState()->GetSavePath() && *GameState()->GetSavePath() && !Emscripten_OPFSDisabled()) {
|
||||||
if (!opfs) {
|
if (!opfs) {
|
||||||
opfs = wasmfs_create_opfs_backend();
|
opfs = wasmfs_create_opfs_backend();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ inline static const char* Emscripten_savePath = "/save";
|
|||||||
inline static const char* Emscripten_streamPath = "/";
|
inline static const char* Emscripten_streamPath = "/";
|
||||||
inline static const char* Emscripten_streamHost = ISLE_EMSCRIPTEN_HOST;
|
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();
|
void Emscripten_SetupFilesystem();
|
||||||
|
|
||||||
#endif // EMSCRIPTEN_FILESYSTEM_H
|
#endif // EMSCRIPTEN_FILESYSTEM_H
|
||||||
|
|||||||
@ -28,7 +28,10 @@
|
|||||||
#include "mxtransitionmanager.h"
|
#include "mxtransitionmanager.h"
|
||||||
#include "mxutilities.h"
|
#include "mxutilities.h"
|
||||||
#include "mxvariabletable.h"
|
#include "mxvariabletable.h"
|
||||||
|
#include "res/arrow_bmp.h"
|
||||||
|
#include "res/busy_bmp.h"
|
||||||
#include "res/isle_bmp.h"
|
#include "res/isle_bmp.h"
|
||||||
|
#include "res/no_bmp.h"
|
||||||
#include "res/resource.h"
|
#include "res/resource.h"
|
||||||
#include "roi/legoroi.h"
|
#include "roi/legoroi.h"
|
||||||
#include "tgl/d3drm/impl.h"
|
#include "tgl/d3drm/impl.h"
|
||||||
@ -142,6 +145,10 @@ IsleApp::IsleApp()
|
|||||||
m_cursorBusy = NULL;
|
m_cursorBusy = NULL;
|
||||||
m_cursorNo = NULL;
|
m_cursorNo = NULL;
|
||||||
m_cursorCurrent = NULL;
|
m_cursorCurrent = NULL;
|
||||||
|
m_cursorArrowBitmap = NULL;
|
||||||
|
m_cursorBusyBitmap = NULL;
|
||||||
|
m_cursorNoBitmap = NULL;
|
||||||
|
m_cursorCurrentBitmap = NULL;
|
||||||
|
|
||||||
LegoOmni::CreateInstance();
|
LegoOmni::CreateInstance();
|
||||||
|
|
||||||
@ -466,7 +473,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
|||||||
|
|
||||||
SDL_Keycode keyCode = event->key.key;
|
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));
|
SDL_SetWindowFullscreen(window, !(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -682,6 +689,12 @@ MxResult IsleApp::SetupWindow()
|
|||||||
m_cursorBusy = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
m_cursorBusy = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
||||||
m_cursorNo = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED);
|
m_cursorNo = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED);
|
||||||
SDL_SetCursor(m_cursorCurrent);
|
SDL_SetCursor(m_cursorCurrent);
|
||||||
|
if (g_isle->GetDrawCursor()) {
|
||||||
|
SDL_HideCursor();
|
||||||
|
m_cursorCurrentBitmap = m_cursorArrowBitmap = &arrow_cursor;
|
||||||
|
m_cursorBusyBitmap = &busy_cursor;
|
||||||
|
m_cursorNoBitmap = &no_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_PropertiesID props = SDL_CreateProperties();
|
SDL_PropertiesID props = SDL_CreateProperties();
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, g_targetWidth);
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, g_targetWidth);
|
||||||
@ -765,6 +778,9 @@ MxResult IsleApp::SetupWindow()
|
|||||||
LegoOmni::GetInstance()->GetInputManager()->SetUseJoystick(m_useJoystick);
|
LegoOmni::GetInstance()->GetInputManager()->SetUseJoystick(m_useJoystick);
|
||||||
LegoOmni::GetInstance()->GetInputManager()->SetJoystickIndex(m_joystickIndex);
|
LegoOmni::GetInstance()->GetInputManager()->SetJoystickIndex(m_joystickIndex);
|
||||||
}
|
}
|
||||||
|
if (LegoOmni::GetInstance()->GetVideoManager() && g_isle->GetDrawCursor()) {
|
||||||
|
LegoOmni::GetInstance()->GetVideoManager()->SetCursorBitmap(m_cursorCurrentBitmap);
|
||||||
|
}
|
||||||
MxDirect3D* d3d = LegoOmni::GetInstance()->GetVideoManager()->GetDirect3D();
|
MxDirect3D* d3d = LegoOmni::GetInstance()->GetVideoManager()->GetDirect3D();
|
||||||
if (d3d) {
|
if (d3d) {
|
||||||
SDL_Log(
|
SDL_Log(
|
||||||
@ -788,6 +804,13 @@ bool IsleApp::LoadConfig()
|
|||||||
{
|
{
|
||||||
char* prefPath = SDL_GetPrefPath("isledecomp", "isle");
|
char* prefPath = SDL_GetPrefPath("isledecomp", "isle");
|
||||||
char* iniConfig;
|
char* iniConfig;
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
if (m_iniPath && !Emscripten_SetupConfig(m_iniPath)) {
|
||||||
|
m_iniPath = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_iniPath) {
|
if (m_iniPath) {
|
||||||
iniConfig = new char[strlen(m_iniPath) + 1];
|
iniConfig = new char[strlen(m_iniPath) + 1];
|
||||||
strcpy(iniConfig, m_iniPath);
|
strcpy(iniConfig, m_iniPath);
|
||||||
@ -803,10 +826,6 @@ bool IsleApp::LoadConfig()
|
|||||||
}
|
}
|
||||||
SDL_Log("Reading configuration from \"%s\"", iniConfig);
|
SDL_Log("Reading configuration from \"%s\"", iniConfig);
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
Emscripten_SetupConfig(iniConfig);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dictionary* dict = iniparser_load(iniConfig);
|
dictionary* dict = iniparser_load(iniConfig);
|
||||||
|
|
||||||
// [library:config]
|
// [library:config]
|
||||||
@ -1052,15 +1071,19 @@ void IsleApp::SetupCursor(Cursor p_cursor)
|
|||||||
switch (p_cursor) {
|
switch (p_cursor) {
|
||||||
case e_cursorArrow:
|
case e_cursorArrow:
|
||||||
m_cursorCurrent = m_cursorArrow;
|
m_cursorCurrent = m_cursorArrow;
|
||||||
|
m_cursorCurrentBitmap = m_cursorArrowBitmap;
|
||||||
break;
|
break;
|
||||||
case e_cursorBusy:
|
case e_cursorBusy:
|
||||||
m_cursorCurrent = m_cursorBusy;
|
m_cursorCurrent = m_cursorBusy;
|
||||||
|
m_cursorCurrentBitmap = m_cursorBusyBitmap;
|
||||||
break;
|
break;
|
||||||
case e_cursorNo:
|
case e_cursorNo:
|
||||||
m_cursorCurrent = m_cursorNo;
|
m_cursorCurrent = m_cursorNo;
|
||||||
|
m_cursorCurrentBitmap = m_cursorNoBitmap;
|
||||||
break;
|
break;
|
||||||
case e_cursorNone:
|
case e_cursorNone:
|
||||||
m_cursorCurrent = NULL;
|
m_cursorCurrent = NULL;
|
||||||
|
m_cursorCurrentBitmap = NULL;
|
||||||
case e_cursorUnused3:
|
case e_cursorUnused3:
|
||||||
case e_cursorUnused4:
|
case e_cursorUnused4:
|
||||||
case e_cursorUnused5:
|
case e_cursorUnused5:
|
||||||
@ -1072,12 +1095,22 @@ void IsleApp::SetupCursor(Cursor p_cursor)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_cursorCurrent != NULL) {
|
if (g_isle->GetDrawCursor()) {
|
||||||
SDL_SetCursor(m_cursorCurrent);
|
if (m_cursorCurrentBitmap == NULL) {
|
||||||
SDL_ShowCursor();
|
VideoManager()->SetCursorBitmap(NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VideoManager()->SetCursorBitmap(m_cursorCurrentBitmap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SDL_HideCursor();
|
if (m_cursorCurrent != NULL) {
|
||||||
|
SDL_SetCursor(m_cursorCurrent);
|
||||||
|
SDL_ShowCursor();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_HideCursor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#ifndef ISLEAPP_H
|
#ifndef ISLEAPP_H
|
||||||
#define ISLEAPP_H
|
#define ISLEAPP_H
|
||||||
|
|
||||||
|
#include "cursor.h"
|
||||||
#include "lego1_export.h"
|
#include "lego1_export.h"
|
||||||
#include "legoutils.h"
|
#include "legoutils.h"
|
||||||
#include "mxtransitionmanager.h"
|
#include "mxtransitionmanager.h"
|
||||||
@ -87,6 +88,10 @@ class IsleApp {
|
|||||||
SDL_Cursor* m_cursorBusy; // 0x80
|
SDL_Cursor* m_cursorBusy; // 0x80
|
||||||
SDL_Cursor* m_cursorNo; // 0x84
|
SDL_Cursor* m_cursorNo; // 0x84
|
||||||
SDL_Cursor* m_cursorCurrent; // 0x88
|
SDL_Cursor* m_cursorCurrent; // 0x88
|
||||||
|
const CursorBitmap* m_cursorArrowBitmap;
|
||||||
|
const CursorBitmap* m_cursorBusyBitmap;
|
||||||
|
const CursorBitmap* m_cursorNoBitmap;
|
||||||
|
const CursorBitmap* m_cursorCurrentBitmap;
|
||||||
char* m_mediaPath;
|
char* m_mediaPath;
|
||||||
|
|
||||||
char* m_iniPath;
|
char* m_iniPath;
|
||||||
|
|||||||
BIN
ISLE/res/arrow.png
Normal file
BIN
ISLE/res/arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 165 B |
37
ISLE/res/arrow_bmp.h
Normal file
37
ISLE/res/arrow_bmp.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Generated from ISLE/res/arrow.png
|
||||||
|
// Dimensions: 32x32
|
||||||
|
// This file is auto-generated, do not edit it.
|
||||||
|
|
||||||
|
#include "cursor.h"
|
||||||
|
|
||||||
|
static const unsigned char arrow_data[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
|
||||||
|
0x48, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
|
||||||
|
0x41, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||||
|
0x40, 0x20, 0x00, 0x00, 0x41, 0xF0, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,
|
||||||
|
0x54, 0x80, 0x00, 0x00, 0x64, 0x80, 0x00, 0x00, 0x42, 0x40, 0x00, 0x00,
|
||||||
|
0x02, 0x40, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char arrow_mask[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||||
|
0x78, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00,
|
||||||
|
0x7F, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00,
|
||||||
|
0x7F, 0xE0, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
|
||||||
|
0x77, 0x80, 0x00, 0x00, 0x67, 0x80, 0x00, 0x00, 0x43, 0xC0, 0x00, 0x00,
|
||||||
|
0x03, 0xC0, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00,
|
||||||
|
0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const CursorBitmap arrow_cursor = { 32, 32, arrow_data, arrow_mask };
|
||||||
BIN
ISLE/res/busy.png
Normal file
BIN
ISLE/res/busy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 173 B |
37
ISLE/res/busy_bmp.h
Normal file
37
ISLE/res/busy_bmp.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Generated from ISLE/res/busy.png
|
||||||
|
// Dimensions: 32x32
|
||||||
|
// This file is auto-generated, do not edit it.
|
||||||
|
|
||||||
|
#include "cursor.h"
|
||||||
|
|
||||||
|
static const unsigned char busy_data[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00,
|
||||||
|
0x00, 0x40, 0x01, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x20, 0x02, 0x00,
|
||||||
|
0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x22, 0xA2, 0x00,
|
||||||
|
0x00, 0x11, 0x44, 0x00, 0x00, 0x08, 0x88, 0x00, 0x00, 0x04, 0x10, 0x00,
|
||||||
|
0x00, 0x02, 0x20, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x02, 0x20, 0x00,
|
||||||
|
0x00, 0x02, 0x20, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x08, 0x88, 0x00,
|
||||||
|
0x00, 0x10, 0x04, 0x00, 0x00, 0x20, 0x82, 0x00, 0x00, 0x21, 0x42, 0x00,
|
||||||
|
0x00, 0x22, 0xA2, 0x00, 0x00, 0x25, 0x52, 0x00, 0x00, 0x7F, 0xFF, 0x00,
|
||||||
|
0x00, 0x40, 0x01, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char busy_mask[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00,
|
||||||
|
0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x3F, 0xFE, 0x00,
|
||||||
|
0x00, 0x3F, 0xFE, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x3F, 0xFE, 0x00,
|
||||||
|
0x00, 0x1F, 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x07, 0xF0, 0x00,
|
||||||
|
0x00, 0x03, 0xE0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x03, 0xE0, 0x00,
|
||||||
|
0x00, 0x03, 0xE0, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x0F, 0xF8, 0x00,
|
||||||
|
0x00, 0x1F, 0xFC, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x3F, 0xFE, 0x00,
|
||||||
|
0x00, 0x3F, 0xFE, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0x00,
|
||||||
|
0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const CursorBitmap busy_cursor = { 32, 32, busy_data, busy_mask };
|
||||||
BIN
ISLE/res/no.png
Normal file
BIN
ISLE/res/no.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 191 B |
37
ISLE/res/no_bmp.h
Normal file
37
ISLE/res/no_bmp.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Generated from ISLE/res/no.png
|
||||||
|
// Dimensions: 32x32
|
||||||
|
// This file is auto-generated, do not edit it.
|
||||||
|
|
||||||
|
#include "cursor.h"
|
||||||
|
|
||||||
|
static const unsigned char no_data[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x1F, 0xF8, 0x00,
|
||||||
|
0x00, 0x3C, 0x3C, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xF8, 0x07, 0x00,
|
||||||
|
0x00, 0xDC, 0x03, 0x00, 0x01, 0xCE, 0x03, 0x80, 0x01, 0x87, 0x01, 0x80,
|
||||||
|
0x01, 0x83, 0x81, 0x80, 0x01, 0x81, 0xC1, 0x80, 0x01, 0x80, 0xE1, 0x80,
|
||||||
|
0x01, 0xC0, 0x73, 0x80, 0x00, 0xC0, 0x3B, 0x00, 0x00, 0xE0, 0x1F, 0x00,
|
||||||
|
0x00, 0x70, 0x0E, 0x00, 0x00, 0x3C, 0x1C, 0x00, 0x00, 0x1F, 0xF8, 0x00,
|
||||||
|
0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char no_mask[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x07, 0xE0, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x3F, 0xFC, 0x00,
|
||||||
|
0x00, 0x7F, 0xFE, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x01, 0xFC, 0x0F, 0x80,
|
||||||
|
0x01, 0xFE, 0x07, 0x80, 0x03, 0xFF, 0x07, 0xC0, 0x03, 0xCF, 0x83, 0xC0,
|
||||||
|
0x03, 0xC7, 0xC3, 0xC0, 0x03, 0xC3, 0xE3, 0xC0, 0x03, 0xC1, 0xF3, 0xC0,
|
||||||
|
0x03, 0xE0, 0xFF, 0xC0, 0x01, 0xE0, 0x7F, 0x80, 0x01, 0xF0, 0x3F, 0x80,
|
||||||
|
0x00, 0xFC, 0x1F, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x3F, 0xFC, 0x00,
|
||||||
|
0x00, 0x1F, 0xF8, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const CursorBitmap no_cursor = { 32, 32, no_data, no_mask };
|
||||||
8
LEGO1/cursor.h
Normal file
8
LEGO1/cursor.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct CursorBitmap {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
const unsigned char* data;
|
||||||
|
const unsigned char* mask;
|
||||||
|
} CursorBitmap;
|
||||||
@ -1,6 +1,7 @@
|
|||||||
#ifndef LEGOVIDEOMANAGER_H
|
#ifndef LEGOVIDEOMANAGER_H
|
||||||
#define LEGOVIDEOMANAGER_H
|
#define LEGOVIDEOMANAGER_H
|
||||||
|
|
||||||
|
#include "cursor.h"
|
||||||
#include "decomp.h"
|
#include "decomp.h"
|
||||||
#include "lego1_export.h"
|
#include "lego1_export.h"
|
||||||
#include "legophonemelist.h"
|
#include "legophonemelist.h"
|
||||||
@ -37,6 +38,7 @@ class LegoVideoManager : public MxVideoManager {
|
|||||||
void EnableFullScreenMovie(MxBool p_enable);
|
void EnableFullScreenMovie(MxBool p_enable);
|
||||||
LEGO1_EXPORT void EnableFullScreenMovie(MxBool p_enable, MxBool p_scale);
|
LEGO1_EXPORT void EnableFullScreenMovie(MxBool p_enable, MxBool p_scale);
|
||||||
LEGO1_EXPORT void MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY);
|
LEGO1_EXPORT void MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY);
|
||||||
|
LEGO1_EXPORT void SetCursorBitmap(const CursorBitmap* p_cursorBitmap);
|
||||||
void ToggleFPS(MxBool p_visible);
|
void ToggleFPS(MxBool p_visible);
|
||||||
|
|
||||||
MxResult Tickle() override; // vtable+0x08
|
MxResult Tickle() override; // vtable+0x08
|
||||||
|
|||||||
@ -48,7 +48,8 @@ class MxTransitionManager : public MxCore {
|
|||||||
e_mosaic,
|
e_mosaic,
|
||||||
e_wipeDown,
|
e_wipeDown,
|
||||||
e_windows,
|
e_windows,
|
||||||
e_broken // Unknown what this is supposed to be, it locks the game up
|
e_broken, // Unknown what this is supposed to be, it locks the game up
|
||||||
|
e_fakeMosaic
|
||||||
};
|
};
|
||||||
|
|
||||||
MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim);
|
MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim);
|
||||||
@ -68,6 +69,7 @@ class MxTransitionManager : public MxCore {
|
|||||||
void WipeDownTransition();
|
void WipeDownTransition();
|
||||||
void WindowsTransition();
|
void WindowsTransition();
|
||||||
void BrokenTransition();
|
void BrokenTransition();
|
||||||
|
void FakeMosaicTransition();
|
||||||
|
|
||||||
void SubmitCopyRect(LPDDSURFACEDESC p_ddsc);
|
void SubmitCopyRect(LPDDSURFACEDESC p_ddsc);
|
||||||
void SetupCopyRect(LPDDSURFACEDESC p_ddsc);
|
void SetupCopyRect(LPDDSURFACEDESC p_ddsc);
|
||||||
|
|||||||
@ -84,6 +84,9 @@ MxResult MxTransitionManager::Tickle()
|
|||||||
case e_broken:
|
case e_broken:
|
||||||
BrokenTransition();
|
BrokenTransition();
|
||||||
break;
|
break;
|
||||||
|
case e_fakeMosaic:
|
||||||
|
FakeMosaicTransition();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@ -400,47 +403,18 @@ void MxTransitionManager::WipeDownTransition()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDSURFACEDESC ddsd;
|
RECT fillRect = g_fullScreenRect;
|
||||||
memset(&ddsd, 0, sizeof(ddsd));
|
// For each of the 240 animation ticks, blank out two scanlines
|
||||||
ddsd.dwSize = sizeof(ddsd);
|
// 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);
|
DDBLTFX bltFx = {};
|
||||||
if (res == DDERR_SURFACELOST) {
|
bltFx.dwSize = sizeof(bltFx);
|
||||||
m_ddSurface->Restore();
|
bltFx.dwFillColor = 0xFF000000;
|
||||||
res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == DD_OK) {
|
m_ddSurface->Blt(&fillRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx);
|
||||||
SubmitCopyRect(&ddsd);
|
|
||||||
|
|
||||||
// For each of the 240 animation ticks, blank out two scanlines
|
m_animationTimer++;
|
||||||
// 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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x1004c270
|
// FUNCTION: LEGO1 0x1004c270
|
||||||
@ -452,65 +426,28 @@ void MxTransitionManager::WindowsTransition()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDSURFACEDESC ddsd;
|
DDBLTFX bltFx = {};
|
||||||
memset(&ddsd, 0, sizeof(ddsd));
|
bltFx.dwSize = sizeof(bltFx);
|
||||||
ddsd.dwSize = sizeof(ddsd);
|
bltFx.dwFillColor = 0xFF000000;
|
||||||
|
|
||||||
HRESULT res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
|
int top = m_animationTimer;
|
||||||
if (res == DDERR_SURFACELOST) {
|
int bottom = 480 - m_animationTimer - 1;
|
||||||
m_ddSurface->Restore();
|
int left = m_animationTimer;
|
||||||
res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
|
int right = 639 - m_animationTimer;
|
||||||
}
|
|
||||||
|
|
||||||
if (res == DD_OK) {
|
RECT topRect = {0, top, 640, top + 1};
|
||||||
SubmitCopyRect(&ddsd);
|
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) {
|
RECT rightRect = {right, top + 1, right + 1, bottom};
|
||||||
MxU32* pixels = (MxU32*) line;
|
m_ddSurface->Blt(&rightRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx);
|
||||||
for (int i = 0; i < 640; i++) {
|
|
||||||
pixels[i] = 0xFF000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MxS32 i = m_animationTimer + 1; i < 480 - m_animationTimer - 1; i++) {
|
m_animationTimer++;
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x1004c3e0
|
// FUNCTION: LEGO1 0x1004c3e0
|
||||||
@ -679,3 +616,128 @@ void MxTransitionManager::configureMxTransitionManager(TransitionType p_transiti
|
|||||||
{
|
{
|
||||||
g_transitionManagerConfig = p_transitionManagerConfig;
|
g_transitionManagerConfig = p_transitionManagerConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int g_colorOffset;
|
||||||
|
int GetColorIndexWithLocality(int p_col, int p_row)
|
||||||
|
{
|
||||||
|
int islandX = p_col / 8;
|
||||||
|
int islandY = p_row / 8; // Dvide screen in 8x6 tiles
|
||||||
|
|
||||||
|
int island = islandY * 8 + islandX; // tile id
|
||||||
|
|
||||||
|
if (SDL_rand(3) > island / 8) {
|
||||||
|
return 6 + SDL_rand(2); // emulate sky
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_rand(16) > 2) {
|
||||||
|
island += SDL_rand(3) - 1 + (SDL_rand(3) - 1) * 8; // blure tiles
|
||||||
|
}
|
||||||
|
|
||||||
|
int hash = (island + g_colorOffset) * 2654435761u;
|
||||||
|
int scrambled = (hash >> 16) % 32;
|
||||||
|
|
||||||
|
int finalIndex = scrambled + SDL_rand(3) - 1;
|
||||||
|
return abs(finalIndex) % 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MxTransitionManager::FakeMosaicTransition()
|
||||||
|
{
|
||||||
|
if (m_animationTimer == 16) {
|
||||||
|
m_animationTimer = 0;
|
||||||
|
EndTransition(TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_animationTimer == 0) {
|
||||||
|
g_colorOffset = SDL_rand(32);
|
||||||
|
for (MxS32 i = 0; i < 64; i++) {
|
||||||
|
m_columnOrder[i] = i;
|
||||||
|
}
|
||||||
|
for (MxS32 i = 0; i < 64; i++) {
|
||||||
|
MxS32 swap = SDL_rand(64);
|
||||||
|
std::swap(m_columnOrder[i], m_columnOrder[swap]);
|
||||||
|
}
|
||||||
|
for (MxS32 i = 0; i < 48; i++) {
|
||||||
|
m_randomShift[i] = SDL_rand(64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DDSURFACEDESC ddsd = {};
|
||||||
|
ddsd.dwSize = sizeof(ddsd);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == DD_OK) {
|
||||||
|
SubmitCopyRect(&ddsd);
|
||||||
|
|
||||||
|
static const MxU8 g_palette[32][3] = {
|
||||||
|
{0x00, 0x00, 0x00}, {0x12, 0x1e, 0x50}, {0x00, 0x22, 0x6c}, {0x14, 0x2d, 0x9f}, {0x0e, 0x36, 0xb0},
|
||||||
|
{0x0e, 0x39, 0xd0}, {0x47, 0x96, 0xe2}, {0x79, 0xaa, 0xca}, {0xff, 0xff, 0xff}, {0xc9, 0xcd, 0xcb},
|
||||||
|
{0xad, 0xad, 0xab}, {0xa6, 0x91, 0x8e}, {0xaf, 0x59, 0x49}, {0xc0, 0x00, 0x00}, {0xab, 0x18, 0x18},
|
||||||
|
{0x61, 0x0c, 0x0c}, {0x04, 0x38, 0x12}, {0x2c, 0x67, 0x28}, {0x4a, 0xb4, 0x6b}, {0x94, 0xb7, 0x7c},
|
||||||
|
{0xb6, 0xb9, 0x87}, {0x52, 0x4a, 0x67}, {0x87, 0x8d, 0x8a}, {0xa6, 0x91, 0x8e}, {0xf8, 0xee, 0xdc},
|
||||||
|
{0xf4, 0xe2, 0xc3}, {0x87, 0x8d, 0x8a}, {0xba, 0x9f, 0x12}, {0xb5, 0x83, 0x00}, {0x6a, 0x44, 0x27},
|
||||||
|
{0x36, 0x37, 0x34}, {0x2b, 0x23, 0x0f}
|
||||||
|
};
|
||||||
|
|
||||||
|
MxS32 bytesPerPixel = ddsd.ddpfPixelFormat.dwRGBBitCount / 8;
|
||||||
|
|
||||||
|
for (MxS32 col = 0; col < 64; col++) {
|
||||||
|
if (m_animationTimer * 4 > m_columnOrder[col]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (m_animationTimer * 4 + 3 < m_columnOrder[col]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MxS32 row = 0; row < 48; row++) {
|
||||||
|
MxS32 xShift = 10 * ((m_randomShift[row] + col) % 64);
|
||||||
|
MxS32 yStart = 10 * row;
|
||||||
|
|
||||||
|
int paletteIndex = GetColorIndexWithLocality(xShift / 10, row);
|
||||||
|
|
||||||
|
const MxU8* color = g_palette[paletteIndex];
|
||||||
|
|
||||||
|
for (MxS32 y = 0; y < 10; y++) {
|
||||||
|
MxU8* dest = (MxU8*) ddsd.lpSurface + (yStart + y) * ddsd.lPitch + xShift * bytesPerPixel;
|
||||||
|
switch (bytesPerPixel) {
|
||||||
|
case 1:
|
||||||
|
memset(dest, paletteIndex, 10);
|
||||||
|
break;
|
||||||
|
case 2: {
|
||||||
|
MxU32 pixel = RGB555_CREATE(color[2], color[1], color[0]);
|
||||||
|
MxU16* p = (MxU16*) dest;
|
||||||
|
for (MxS32 i = 0; i < 10; i++) {
|
||||||
|
p[i] = pixel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
MxU32 pixel = RGB8888_CREATE(color[2], color[1], color[0], 255);
|
||||||
|
MxU32* p = (MxU32*) dest;
|
||||||
|
for (MxS32 i = 0; i < 10; i++) {
|
||||||
|
p[i] = pixel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupCopyRect(&ddsd);
|
||||||
|
m_ddSurface->Unlock(ddsd.lpSurface);
|
||||||
|
|
||||||
|
if (VideoManager()->GetVideoParam().Flags().GetFlipSurfaces()) {
|
||||||
|
VideoManager()
|
||||||
|
->GetDisplaySurface()
|
||||||
|
->GetDirectDrawSurface1()
|
||||||
|
->BltFast(0, 0, m_ddSurface, &g_fullScreenRect, DDBLTFAST_WAIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_animationTimer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -272,14 +272,13 @@ void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY)
|
|||||||
{
|
{
|
||||||
m_cursorX = p_cursorX;
|
m_cursorX = p_cursorX;
|
||||||
m_cursorY = p_cursorY;
|
m_cursorY = p_cursorY;
|
||||||
m_drawCursor = TRUE;
|
|
||||||
|
|
||||||
if (623 < p_cursorX) {
|
if (640 < p_cursorX) {
|
||||||
m_cursorX = 623;
|
m_cursorX = 640;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (463 < p_cursorY) {
|
if (480 < p_cursorY) {
|
||||||
m_cursorY = 463;
|
m_cursorY = 480;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,15 +387,7 @@ inline void LegoVideoManager::DrawCursor()
|
|||||||
LPDIRECTDRAWSURFACE ddSurface2 = m_displaySurface->GetDirectDrawSurface2();
|
LPDIRECTDRAWSURFACE ddSurface2 = m_displaySurface->GetDirectDrawSurface2();
|
||||||
|
|
||||||
if (!m_cursorSurface) {
|
if (!m_cursorSurface) {
|
||||||
m_cursorRect.top = 0;
|
return;
|
||||||
m_cursorRect.left = 0;
|
|
||||||
m_cursorRect.bottom = 16;
|
|
||||||
m_cursorRect.right = 16;
|
|
||||||
m_cursorSurface = MxDisplaySurface::CreateCursorSurface();
|
|
||||||
|
|
||||||
if (!m_cursorSurface) {
|
|
||||||
m_drawCursor = FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ddSurface2
|
ddSurface2
|
||||||
@ -836,3 +827,30 @@ void LegoVideoManager::DrawTextToSurface32(
|
|||||||
++p_text;
|
++p_text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LegoVideoManager::SetCursorBitmap(const CursorBitmap* p_cursorBitmap)
|
||||||
|
{
|
||||||
|
if (p_cursorBitmap == NULL) {
|
||||||
|
m_drawCursor = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_cursorSurface != NULL) {
|
||||||
|
m_cursorSurface->Release();
|
||||||
|
m_cursorSurface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cursorRect.top = 0;
|
||||||
|
m_cursorRect.left = 0;
|
||||||
|
m_cursorRect.bottom = p_cursorBitmap->height;
|
||||||
|
m_cursorRect.right = p_cursorBitmap->width;
|
||||||
|
|
||||||
|
m_cursorSurface = MxDisplaySurface::CreateCursorSurface(p_cursorBitmap);
|
||||||
|
|
||||||
|
if (m_cursorSurface == NULL) {
|
||||||
|
m_drawCursor = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_drawCursor = TRUE;
|
||||||
|
}
|
||||||
|
|||||||
@ -22,10 +22,9 @@ LegoTextureInfo* LegoTextureContainer::GetCached(LegoTextureInfo* p_textureInfo)
|
|||||||
memset(&desc, 0, sizeof(desc));
|
memset(&desc, 0, sizeof(desc));
|
||||||
desc.dwSize = 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;
|
width = desc.dwWidth;
|
||||||
height = desc.dwHeight;
|
height = desc.dwHeight;
|
||||||
p_textureInfo->m_surface->Unlock(desc.lpSurface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (LegoCachedTextureList::iterator it = m_cached.begin(); it != m_cached.end(); it++) {
|
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));
|
memset(&newDesc, 0, sizeof(newDesc));
|
||||||
newDesc.dwSize = sizeof(newDesc);
|
newDesc.dwSize = sizeof(newDesc);
|
||||||
|
|
||||||
if (surface->Lock(NULL, &newDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL) == DD_OK) {
|
if (surface->GetSurfaceDesc(&newDesc) == DD_OK) {
|
||||||
BOOL und = FALSE;
|
|
||||||
if (newDesc.dwWidth == width && newDesc.dwHeight == height) {
|
if (newDesc.dwWidth == width && newDesc.dwHeight == height) {
|
||||||
und = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->Unlock(newDesc.lpSurface);
|
|
||||||
|
|
||||||
if (und) {
|
|
||||||
(*it).second = TRUE;
|
(*it).second = TRUE;
|
||||||
(*it).first->m_texture->AddRef();
|
(*it).first->m_texture->AddRef();
|
||||||
return (*it).first;
|
return (*it).first;
|
||||||
|
|||||||
@ -172,7 +172,7 @@ BOOL MxDirect3D::D3DSetMode()
|
|||||||
|
|
||||||
DDBLTFX ddBltFx = {};
|
DDBLTFX ddBltFx = {};
|
||||||
ddBltFx.dwSize = sizeof(DDBLTFX);
|
ddBltFx.dwSize = sizeof(DDBLTFX);
|
||||||
ddBltFx.dwFillColor = 0;
|
ddBltFx.dwFillColor = 0xFF000000;
|
||||||
|
|
||||||
if (backBuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx) != DD_OK) {
|
if (backBuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx) != DD_OK) {
|
||||||
SDL_Log("MxDirect3D::D3DSetMode() color fill failed\n");
|
SDL_Log("MxDirect3D::D3DSetMode() color fill failed\n");
|
||||||
|
|||||||
@ -519,35 +519,23 @@ BOOL MxDirectDraw::DDCreateSurfaces()
|
|||||||
void MxDirectDraw::ClearBackBuffers()
|
void MxDirectDraw::ClearBackBuffers()
|
||||||
{
|
{
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
byte* line;
|
DDBLTFX ddbltfx = {};
|
||||||
DDSURFACEDESC ddsd;
|
ddbltfx.dwSize = sizeof(DDBLTFX);
|
||||||
|
ddbltfx.dwFillColor = 0xFF000000;
|
||||||
int count = m_bFlipSurfaces ? 2 : 1;
|
int count = m_bFlipSurfaces ? 2 : 1;
|
||||||
int value = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
memset(&ddsd, 0, sizeof(ddsd));
|
result = m_pBackBuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
|
||||||
ddsd.dwSize = sizeof(ddsd);
|
|
||||||
|
|
||||||
result = m_pBackBuffer->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
|
|
||||||
if (result == DDERR_SURFACELOST) {
|
if (result == DDERR_SURFACELOST) {
|
||||||
m_pBackBuffer->Restore();
|
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) {
|
if (result != DD_OK) {
|
||||||
// lock failed
|
// blt failed
|
||||||
return;
|
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) {
|
if (m_bFlipSurfaces) {
|
||||||
m_pFrontBuffer->Flip(NULL, DDFLIP_WAIT);
|
m_pFrontBuffer->Flip(NULL, DDFLIP_WAIT);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#ifndef MXDISPLAYSURFACE_H
|
#ifndef MXDISPLAYSURFACE_H
|
||||||
#define MXDISPLAYSURFACE_H
|
#define MXDISPLAYSURFACE_H
|
||||||
|
|
||||||
|
#include "cursor.h"
|
||||||
#include "decomp.h"
|
#include "decomp.h"
|
||||||
#include "mxcore.h"
|
#include "mxcore.h"
|
||||||
#include "mxvideoparam.h"
|
#include "mxvideoparam.h"
|
||||||
@ -11,6 +12,9 @@
|
|||||||
#include <ddraw.h>
|
#include <ddraw.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RGB555_CREATE(R, G, B) (((R) << 10) | (G) << 5 | (B) << 0)
|
||||||
|
#define RGB8888_CREATE(R, G, B, A) (((A) << 24) | ((R) << 16) | ((G) << 8) | (B))
|
||||||
|
|
||||||
class MxBitmap;
|
class MxBitmap;
|
||||||
class MxPalette;
|
class MxPalette;
|
||||||
|
|
||||||
@ -70,14 +74,6 @@ class MxDisplaySurface : public MxCore {
|
|||||||
MxS32 p_height,
|
MxS32 p_height,
|
||||||
MxBool p_RLE
|
MxBool p_RLE
|
||||||
); // vtable+0x30
|
); // 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(
|
virtual void Display(
|
||||||
MxS32 p_left,
|
MxS32 p_left,
|
||||||
MxS32 p_top,
|
MxS32 p_top,
|
||||||
@ -96,7 +92,7 @@ class MxDisplaySurface : public MxCore {
|
|||||||
); // vtable+0x44
|
); // vtable+0x44
|
||||||
|
|
||||||
void ClearScreen();
|
void ClearScreen();
|
||||||
static LPDIRECTDRAWSURFACE CreateCursorSurface();
|
static LPDIRECTDRAWSURFACE CreateCursorSurface(const CursorBitmap* p_cursorBitmap);
|
||||||
static LPDIRECTDRAWSURFACE CopySurface(LPDIRECTDRAWSURFACE p_src);
|
static LPDIRECTDRAWSURFACE CopySurface(LPDIRECTDRAWSURFACE p_src);
|
||||||
|
|
||||||
LPDIRECTDRAWSURFACE GetDirectDrawSurface1() { return m_ddSurface1; }
|
LPDIRECTDRAWSURFACE GetDirectDrawSurface1() { return m_ddSurface1; }
|
||||||
|
|||||||
@ -18,9 +18,6 @@
|
|||||||
|
|
||||||
DECOMP_SIZE_ASSERT(MxDisplaySurface, 0xac);
|
DECOMP_SIZE_ASSERT(MxDisplaySurface, 0xac);
|
||||||
|
|
||||||
#define RGB555_CREATE(R, G, B) (((R) << 10) | (G) << 5 | (B) << 0)
|
|
||||||
#define RGB8888_CREATE(R, G, B, A) (((A) << 24) | ((R) << 16) | ((G) << 8) | (B))
|
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x1010215c
|
// GLOBAL: LEGO1 0x1010215c
|
||||||
MxU32 g_unk0x1010215c = 0;
|
MxU32 g_unk0x1010215c = 0;
|
||||||
|
|
||||||
@ -72,7 +69,7 @@ void MxDisplaySurface::ClearScreen()
|
|||||||
|
|
||||||
DDBLTFX ddBltFx = {};
|
DDBLTFX ddBltFx = {};
|
||||||
ddBltFx.dwSize = sizeof(DDBLTFX);
|
ddBltFx.dwSize = sizeof(DDBLTFX);
|
||||||
ddBltFx.dwFillColor = 0;
|
ddBltFx.dwFillColor = 0xFF000000;
|
||||||
|
|
||||||
for (MxS32 i = 0; i < backBuffers; i++) {
|
for (MxS32 i = 0; i < backBuffers; i++) {
|
||||||
if (m_ddSurface2->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddBltFx) == DDERR_SURFACELOST) {
|
if (m_ddSurface2->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddBltFx) == DDERR_SURFACELOST) {
|
||||||
@ -399,86 +396,81 @@ void MxDisplaySurface::VTable0x28(
|
|||||||
DDSURFACEDESC ddsd;
|
DDSURFACEDESC ddsd;
|
||||||
memset(&ddsd, 0, sizeof(ddsd));
|
memset(&ddsd, 0, sizeof(ddsd));
|
||||||
ddsd.dwSize = sizeof(ddsd);
|
ddsd.dwSize = sizeof(ddsd);
|
||||||
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
|
||||||
|
ddsd.dwWidth = p_width;
|
||||||
|
ddsd.dwHeight = p_height;
|
||||||
|
ddsd.ddpfPixelFormat = m_surfaceDesc.ddpfPixelFormat;
|
||||||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||||||
|
|
||||||
HRESULT hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
|
LPDIRECTDRAWSURFACE tempSurface = nullptr;
|
||||||
|
LPDIRECTDRAW draw = MVideoManager()->GetDirectDraw();
|
||||||
|
HRESULT hr = draw->CreateSurface(&ddsd, &tempSurface, nullptr);
|
||||||
|
if (hr != DD_OK || !tempSurface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDCOLORKEY colorKey;
|
||||||
|
colorKey.dwColorSpaceLowValue = colorKey.dwColorSpaceHighValue = RGB555_CREATE(0x1f, 0, 0x1f);
|
||||||
|
tempSurface->SetColorKey(DDCKEY_SRCBLT, &colorKey);
|
||||||
|
|
||||||
|
DDSURFACEDESC tempDesc;
|
||||||
|
memset(&tempDesc, 0, sizeof(tempDesc));
|
||||||
|
tempDesc.dwSize = sizeof(tempDesc);
|
||||||
|
|
||||||
|
hr = tempSurface->Lock(NULL, &tempDesc, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
|
||||||
if (hr == DDERR_SURFACELOST) {
|
if (hr == DDERR_SURFACELOST) {
|
||||||
m_ddSurface2->Restore();
|
tempSurface->Restore();
|
||||||
hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
|
hr = tempSurface->Lock(NULL, &tempDesc, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hr != DD_OK) {
|
if (hr != DD_OK) {
|
||||||
|
tempSurface->Release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MxU8* data = p_bitmap->GetStart(p_left, p_top);
|
MxU8* data = p_bitmap->GetStart(p_left, p_top);
|
||||||
|
|
||||||
MxS32 bytesPerPixel = m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount / 8;
|
MxS32 bytesPerPixel = m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount / 8;
|
||||||
if (m_videoParam.Flags().GetF1bit3()) {
|
MxU8* surface = (MxU8*) tempDesc.lpSurface;
|
||||||
p_bottom *= 2;
|
|
||||||
p_right *= 2;
|
|
||||||
|
|
||||||
MxU8* surface = (MxU8*) ddsd.lpSurface + (bytesPerPixel * p_right) + (p_bottom * ddsd.lPitch);
|
MxLong stride = (bytesPerPixel == 1) ? GetAdjustedStride(p_bitmap) : -p_width + GetAdjustedStride(p_bitmap);
|
||||||
MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
|
MxLong length = tempDesc.lPitch - (p_width * bytesPerPixel);
|
||||||
MxS32 copyWidth = p_width * bytesPerPixel * 2;
|
|
||||||
MxLong length = -(copyWidth) + ddsd.lPitch;
|
|
||||||
|
|
||||||
while (p_height--) {
|
for (MxS32 i = 0; i < p_height; i++) {
|
||||||
MxU8* surfaceBefore = surface;
|
if (bytesPerPixel == 1) {
|
||||||
|
memcpy(surface, data, p_width);
|
||||||
for (MxS32 i = 0; i < p_width; i++) {
|
surface += length + p_width;
|
||||||
if (bytesPerPixel == 1) {
|
|
||||||
surface[0] = surface[1] = *data;
|
|
||||||
}
|
|
||||||
else if (bytesPerPixel == 2) {
|
|
||||||
((MxU16*) surface)[0] = ((MxU16*) surface)[1] = m_16bitPal[*data];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
((MxU32*) surface)[0] = ((MxU32*) surface)[1] = m_32bitPal[*data];
|
|
||||||
}
|
|
||||||
surface += bytesPerPixel * 2;
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stride || length != ddsd.lPitch - copyWidth) {
|
|
||||||
data += stride;
|
|
||||||
surface += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(surface, surfaceBefore, copyWidth);
|
|
||||||
surface += ddsd.lPitch;
|
|
||||||
}
|
}
|
||||||
|
else if (bytesPerPixel == 2) {
|
||||||
|
for (MxS32 j = 0; j < p_width; j++) {
|
||||||
|
*(MxU16*) surface = m_16bitPal[*data++];
|
||||||
|
surface += bytesPerPixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface += length;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (MxS32 j = 0; j < p_width; j++) {
|
||||||
|
*(MxU32*) surface = m_32bitPal[*data++];
|
||||||
|
surface += bytesPerPixel;
|
||||||
|
}
|
||||||
|
surface += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
data += stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
tempSurface->Unlock(NULL);
|
||||||
|
|
||||||
|
if (m_videoParam.Flags().GetF1bit3()) {
|
||||||
|
RECT destRect = {p_right, p_bottom, p_right + p_width * 2, p_bottom + p_height * 2};
|
||||||
|
m_ddSurface2->Blt(&destRect, tempSurface, NULL, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MxU8* surface = (MxU8*) ddsd.lpSurface + (bytesPerPixel * p_right) + (p_bottom * ddsd.lPitch);
|
m_ddSurface2->BltFast(p_right, p_bottom, tempSurface, NULL, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
|
||||||
MxLong stride = (bytesPerPixel == 1) ? GetAdjustedStride(p_bitmap) : -p_width + GetAdjustedStride(p_bitmap);
|
|
||||||
MxLong length = ddsd.lPitch - (p_width * bytesPerPixel);
|
|
||||||
|
|
||||||
for (MxS32 i = 0; i < p_height; i++) {
|
|
||||||
if (bytesPerPixel == 1) {
|
|
||||||
memcpy(surface, data, p_width);
|
|
||||||
surface += length + p_width;
|
|
||||||
}
|
|
||||||
else if (bytesPerPixel == 2) {
|
|
||||||
for (MxS32 j = 0; j < p_width; j++) {
|
|
||||||
*(MxU16*) surface = m_16bitPal[*data++];
|
|
||||||
surface += bytesPerPixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface += length;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (MxS32 j = 0; j < p_width; j++) {
|
|
||||||
*(MxU32*) surface = m_32bitPal[*data++];
|
|
||||||
surface += bytesPerPixel;
|
|
||||||
}
|
|
||||||
surface += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
data += stride;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ddSurface2->Unlock(ddsd.lpSurface);
|
tempSurface->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x100bb1d0
|
// FUNCTION: LEGO1 0x100bb1d0
|
||||||
@ -716,61 +708,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
|
// FUNCTION: LEGO1 0x100bba50
|
||||||
void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p_top2, MxS32 p_width, MxS32 p_height)
|
void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p_top2, MxS32 p_width, MxS32 p_height)
|
||||||
{
|
{
|
||||||
@ -779,21 +716,11 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p
|
|||||||
if (g_unk0x1010215c < 2) {
|
if (g_unk0x1010215c < 2) {
|
||||||
g_unk0x1010215c++;
|
g_unk0x1010215c++;
|
||||||
|
|
||||||
DDSURFACEDESC ddsd;
|
DDBLTFX ddbltfx = {};
|
||||||
memset(&ddsd, 0, sizeof(ddsd));
|
ddbltfx.dwSize = sizeof(ddbltfx);
|
||||||
ddsd.dwSize = sizeof(ddsd);
|
ddbltfx.dwFillColor = 0xFF000000;
|
||||||
if (m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL) == DD_OK) {
|
|
||||||
MxU8* surface = (MxU8*) ddsd.lpSurface;
|
|
||||||
MxS32 height = m_videoParam.GetRect().GetHeight();
|
|
||||||
|
|
||||||
for (MxU32 i = 0; i < ddsd.dwHeight; i++) {
|
if (m_ddSurface2->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx) != DD_OK) {
|
||||||
memset(surface, 0, ddsd.lPitch);
|
|
||||||
surface += ddsd.lPitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ddSurface2->Unlock(ddsd.lpSurface);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDisplaySurface::Display error\n");
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDisplaySurface::Display error\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -812,7 +739,7 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p
|
|||||||
DDBLTFX data;
|
DDBLTFX data;
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.dwSize = 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) {
|
if (m_ddSurface1->Blt((LPRECT) &b, m_ddSurface2, (LPRECT) &a, DDBLT_NONE, &data) == DDERR_SURFACELOST) {
|
||||||
m_ddSurface1->Restore();
|
m_ddSurface1->Restore();
|
||||||
@ -1015,86 +942,6 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::CopySurface(LPDIRECTDRAWSURFACE p_src)
|
|||||||
return newSurface;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ddsd.ddpfPixelFormat.dwRGBBitCount != 16) {
|
|
||||||
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
|
// FUNCTION: LEGO1 0x100bc200
|
||||||
void MxDisplaySurface::VTable0x24(
|
void MxDisplaySurface::VTable0x24(
|
||||||
LPDDSURFACEDESC p_desc,
|
LPDDSURFACEDESC p_desc,
|
||||||
@ -1296,3 +1143,125 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::FUN_100bc8b0(MxS32 p_width, MxS32 p_height
|
|||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LPDIRECTDRAWSURFACE MxDisplaySurface::CreateCursorSurface(const CursorBitmap* p_cursorBitmap)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
MxS32 bytesPerPixel = ddsd.ddpfPixelFormat.dwRGBBitCount / 8;
|
||||||
|
|
||||||
|
ddsd.dwWidth = p_cursorBitmap->width;
|
||||||
|
ddsd.dwHeight = p_cursorBitmap->height;
|
||||||
|
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 {
|
||||||
|
for (int y = 0; y < p_cursorBitmap->height; y++) {
|
||||||
|
for (int x = 0; x < p_cursorBitmap->width; x++) {
|
||||||
|
MxS32 bitIndex = y * p_cursorBitmap->width + x;
|
||||||
|
MxS32 byteIndex = bitIndex / 8;
|
||||||
|
MxS32 bitOffset = 7 - (bitIndex % 8);
|
||||||
|
|
||||||
|
MxBool isOpaque = (p_cursorBitmap->mask[byteIndex] >> bitOffset) & 1;
|
||||||
|
MxBool isBlack = (p_cursorBitmap->data[byteIndex] >> bitOffset) & 1;
|
||||||
|
|
||||||
|
switch (bytesPerPixel) {
|
||||||
|
case 1: {
|
||||||
|
MxU8* surface = (MxU8*) ddsd.lpSurface;
|
||||||
|
|
||||||
|
MxU8 pixel;
|
||||||
|
if (!isOpaque) {
|
||||||
|
pixel = 0x10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pixel = isBlack ? 0 : 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
MxU16* surface = (MxU16*) ddsd.lpSurface;
|
||||||
|
|
||||||
|
MxU16 pixel;
|
||||||
|
if (!isOpaque) {
|
||||||
|
pixel = RGB555_CREATE(0x1f, 0, 0x1f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pixel = isBlack ? RGB555_CREATE(0, 0, 0) : RGB555_CREATE(0x1f, 0x1f, 0x1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
surface[x + y * p_cursorBitmap->width] = pixel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
MxU32* surface = (MxU32*) ddsd.lpSurface;
|
||||||
|
|
||||||
|
MxS32 pixel;
|
||||||
|
if (!isOpaque) {
|
||||||
|
pixel = RGB8888_CREATE(0, 0, 0, 0); // Transparent pixel
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pixel = isBlack ? RGB8888_CREATE(0, 0, 0, 0xff) : RGB8888_CREATE(0xff, 0xff, 0xff, 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
surface[x + y * p_cursorBitmap->width] = pixel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newSurface->Unlock(ddsd.lpSurface);
|
||||||
|
switch (bytesPerPixel) {
|
||||||
|
case 1: {
|
||||||
|
DDCOLORKEY colorkey;
|
||||||
|
colorkey.dwColorSpaceHighValue = 0x10;
|
||||||
|
colorkey.dwColorSpaceLowValue = 0x10;
|
||||||
|
newSurface->SetColorKey(DDCKEY_SRCBLT, &colorkey);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
DDCOLORKEY colorkey;
|
||||||
|
colorkey.dwColorSpaceHighValue = RGB555_CREATE(0x1f, 0, 0x1f);
|
||||||
|
colorkey.dwColorSpaceLowValue = RGB555_CREATE(0x1f, 0, 0x1f);
|
||||||
|
newSurface->SetColorKey(DDCKEY_SRCBLT, &colorkey);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (newSurface) {
|
||||||
|
newSurface->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
@ -275,61 +275,37 @@ void MxVideoPresenter::PutFrame()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MxRegionCursor cursor(region);
|
RECT src, dest;
|
||||||
MxRect32* regionRect;
|
|
||||||
|
|
||||||
while ((regionRect = cursor.Next(rect))) {
|
if (m_unk0x58) {
|
||||||
if (regionRect->GetWidth() >= 1 && regionRect->GetHeight() >= 1) {
|
src.left = 0;
|
||||||
RECT src, dest;
|
src.top = 0;
|
||||||
|
src.right = GetWidth();
|
||||||
|
src.bottom = GetHeight();
|
||||||
|
|
||||||
if (m_unk0x58) {
|
dest.left = GetX();
|
||||||
src.left = regionRect->GetLeft() - GetX();
|
dest.top = GetY();
|
||||||
src.top = regionRect->GetTop() - GetY();
|
dest.right = dest.left + GetWidth();
|
||||||
src.right = src.left + regionRect->GetWidth();
|
dest.bottom = dest.top + GetHeight();
|
||||||
src.bottom = src.top + regionRect->GetHeight();
|
}
|
||||||
|
|
||||||
dest.left = regionRect->GetLeft();
|
if (m_action->GetFlags() & MxDSAction::c_bit4) {
|
||||||
dest.top = regionRect->GetTop();
|
if (m_unk0x58) {
|
||||||
dest.right = dest.left + regionRect->GetWidth();
|
if (PrepareRects(src, dest) >= 0) {
|
||||||
dest.bottom = dest.top + regionRect->GetHeight();
|
ddSurface->Blt(&dest, m_unk0x58, &src, DDBLT_KEYSRC, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
if (m_action->GetFlags() & MxDSAction::c_bit4) {
|
|
||||||
if (m_unk0x58) {
|
|
||||||
if (PrepareRects(src, dest) >= 0) {
|
|
||||||
ddSurface->Blt(&dest, m_unk0x58, &src, DDBLT_KEYSRC, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
displaySurface->VTable0x30(
|
|
||||||
m_frameBitmap,
|
|
||||||
regionRect->GetLeft() - GetX(),
|
|
||||||
regionRect->GetTop() - GetY(),
|
|
||||||
regionRect->GetLeft(),
|
|
||||||
regionRect->GetTop(),
|
|
||||||
regionRect->GetWidth(),
|
|
||||||
regionRect->GetHeight(),
|
|
||||||
FALSE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_unk0x58) {
|
|
||||||
if (PrepareRects(src, dest) >= 0) {
|
|
||||||
ddSurface->Blt(&dest, m_unk0x58, &src, DDBLT_NONE, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
displaySurface->VTable0x28(
|
|
||||||
m_frameBitmap,
|
|
||||||
regionRect->GetLeft() - GetX(),
|
|
||||||
regionRect->GetTop() - GetY(),
|
|
||||||
regionRect->GetLeft(),
|
|
||||||
regionRect->GetTop(),
|
|
||||||
regionRect->GetWidth(),
|
|
||||||
regionRect->GetHeight()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
displaySurface->VTable0x30(m_frameBitmap, 0, 0, GetX(), GetY(), GetWidth(), GetHeight(), FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_unk0x58) {
|
||||||
|
if (PrepareRects(src, dest) >= 0) {
|
||||||
|
ddSurface->Blt(&dest, m_unk0x58, &src, DDBLT_NONE, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
displaySurface->VTable0x28(m_frameBitmap, 0, 0, GetX(), GetY(), GetWidth(), GetHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -246,9 +246,13 @@ struct DDSCAPS {
|
|||||||
};
|
};
|
||||||
typedef struct DDSCAPS* LPDDSCAPS;
|
typedef struct DDSCAPS* LPDDSCAPS;
|
||||||
|
|
||||||
|
#define DDBLTFX_NOTEARING DDBLTFXFlags::NOTEARING
|
||||||
|
enum class DDBLTFXFlags : uint8_t {
|
||||||
|
NOTEARING = 1 << 3,
|
||||||
|
};
|
||||||
struct DDBLTFX {
|
struct DDBLTFX {
|
||||||
DWORD dwSize;
|
DWORD dwSize;
|
||||||
DWORD dwDDFX;
|
DDBLTFXFlags dwDDFX;
|
||||||
DWORD dwROP;
|
DWORD dwROP;
|
||||||
DWORD dwFillColor;
|
DWORD dwFillColor;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -26,7 +26,7 @@ Citro3DRenderer::Citro3DRenderer(DWORD width, DWORD height)
|
|||||||
m_virtualWidth = width;
|
m_virtualWidth = width;
|
||||||
m_virtualHeight = height;
|
m_virtualHeight = height;
|
||||||
|
|
||||||
gfxInitDefault();
|
gfxSetScreenFormat(GFX_BOTTOM, GSP_BGR8_OES);
|
||||||
consoleInit(GFX_TOP, nullptr);
|
consoleInit(GFX_TOP, nullptr);
|
||||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||||
|
|
||||||
@ -66,7 +66,6 @@ Citro3DRenderer::~Citro3DRenderer()
|
|||||||
shaderProgramFree(&program);
|
shaderProgramFree(&program);
|
||||||
DVLB_Free(vshader_dvlb);
|
DVLB_Free(vshader_dvlb);
|
||||||
C3D_Fini();
|
C3D_Fini();
|
||||||
gfxExit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Citro3DRenderer::PushLights(const SceneLight* lights, size_t count)
|
void Citro3DRenderer::PushLights(const SceneLight* lights, size_t count)
|
||||||
@ -444,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(
|
void Citro3DRenderer::SubmitDraw(
|
||||||
DWORD meshId,
|
DWORD meshId,
|
||||||
const D3DRMMATRIX4D& modelViewMatrix,
|
const D3DRMMATRIX4D& modelViewMatrix,
|
||||||
@ -463,32 +488,17 @@ void Citro3DRenderer::SubmitDraw(
|
|||||||
BufInfo_Init(bufInfo);
|
BufInfo_Init(bufInfo);
|
||||||
BufInfo_Add(bufInfo, mesh.vbo, sizeof(D3DRMVERTEX), 3, 0x210);
|
BufInfo_Add(bufInfo, mesh.vbo, sizeof(D3DRMVERTEX), 3, 0x210);
|
||||||
|
|
||||||
C3D_FVUnifSet(
|
SetMaterialAppearance(
|
||||||
GPU_VERTEX_SHADER,
|
{appearance.color.r / 255.0f,
|
||||||
|
appearance.color.g / 255.0f,
|
||||||
|
appearance.color.b / 255.0f,
|
||||||
|
appearance.color.a / 255.0f},
|
||||||
|
appearance.shininess,
|
||||||
uLoc_meshColor,
|
uLoc_meshColor,
|
||||||
appearance.color.r / 255.0f,
|
uLoc_shininess,
|
||||||
appearance.color.g / 255.0f,
|
appearance.textureId != NO_TEXTURE_ID ? &m_textures[appearance.textureId].c3dTex : nullptr
|
||||||
appearance.color.b / 255.0f,
|
|
||||||
appearance.color.a / 255.0f
|
|
||||||
);
|
);
|
||||||
|
|
||||||
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);
|
C3D_DrawArrays(GPU_TRIANGLES, 0, mesh.vertexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,7 +530,7 @@ void Citro3DRenderer::Flip()
|
|||||||
g_rendering = false;
|
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);
|
C3D_AlphaBlend(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
|
||||||
StartFrame();
|
StartFrame();
|
||||||
@ -546,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 + 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_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);
|
C3DTextureCacheEntry* texture = (textureId != NO_TEXTURE_ID) ? &m_textures[textureId] : nullptr;
|
||||||
C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_meshColor, 1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
|
|
||||||
C3DTextureCacheEntry& texture = m_textures[textureId];
|
SetMaterialAppearance(color, 0.0f, uLoc_meshColor, uLoc_shininess, texture ? &texture->c3dTex : nullptr);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
float scale = m_viewportTransform.scale;
|
float scale = m_viewportTransform.scale;
|
||||||
|
|
||||||
@ -564,10 +567,17 @@ void Citro3DRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con
|
|||||||
float x2 = x1 + static_cast<float>(dstRect.w);
|
float x2 = x1 + static_cast<float>(dstRect.w);
|
||||||
float y2 = y1 + static_cast<float>(dstRect.h);
|
float y2 = y1 + static_cast<float>(dstRect.h);
|
||||||
|
|
||||||
float u0 = (srcRect.x * scale) / texture.width;
|
float u0 = 0.0f;
|
||||||
float u1 = ((srcRect.x + srcRect.w) * scale) / texture.width;
|
float u1 = 0.0f;
|
||||||
float v0 = (srcRect.y * scale) / texture.height;
|
float v0 = 0.0f;
|
||||||
float v1 = ((srcRect.y + srcRect.h) * scale) / texture.height;
|
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);
|
C3D_ImmDrawBegin(GPU_TRIANGLES);
|
||||||
|
|
||||||
|
|||||||
@ -297,44 +297,23 @@ D3DMATRIX ToD3DMATRIX(const Matrix4x4& in)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actual_SubmitDraw(
|
void SetMaterialAndTexture(const FColor& color, float shininess, IDirect3DTexture9* texture)
|
||||||
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);
|
|
||||||
|
|
||||||
D3DMATERIAL9 mat = {};
|
D3DMATERIAL9 mat = {};
|
||||||
mat.Diffuse.r = appearance->color.r / 255.0f;
|
mat.Diffuse.r = color.r / 255.0f;
|
||||||
mat.Diffuse.g = appearance->color.g / 255.0f;
|
mat.Diffuse.g = color.g / 255.0f;
|
||||||
mat.Diffuse.b = appearance->color.b / 255.0f;
|
mat.Diffuse.b = color.b / 255.0f;
|
||||||
mat.Diffuse.a = appearance->color.a / 255.0f;
|
mat.Diffuse.a = color.a / 255.0f;
|
||||||
mat.Ambient = mat.Diffuse;
|
mat.Ambient = mat.Diffuse;
|
||||||
|
|
||||||
if (appearance->shininess != 0) {
|
if (shininess != 0) {
|
||||||
g_device->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
|
g_device->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
|
||||||
mat.Specular.r = 1.0f;
|
mat.Specular = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
mat.Specular.g = 1.0f;
|
mat.Power = shininess;
|
||||||
mat.Specular.b = 1.0f;
|
|
||||||
mat.Specular.a = 1.0f;
|
|
||||||
mat.Power = appearance->shininess;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g_device->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
g_device->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
||||||
mat.Specular.r = 0.0f;
|
mat.Specular = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
mat.Specular.g = 0.0f;
|
|
||||||
mat.Specular.b = 0.0f;
|
|
||||||
mat.Specular.a = 0.0f;
|
|
||||||
mat.Power = 0.0f;
|
mat.Power = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,6 +331,33 @@ void Actual_SubmitDraw(
|
|||||||
else {
|
else {
|
||||||
g_device->SetTexture(0, nullptr);
|
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);
|
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);
|
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();
|
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_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||||
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||||
|
|
||||||
g_device->SetTexture(0, texture);
|
SetMaterialAndTexture(color, 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);
|
|
||||||
|
|
||||||
D3DSURFACE_DESC texDesc;
|
D3DSURFACE_DESC texDesc;
|
||||||
texture->GetLevelDesc(0, &texDesc);
|
texture->GetLevelDesc(0, &texDesc);
|
||||||
|
|||||||
@ -78,5 +78,5 @@ void Actual_SubmitDraw(
|
|||||||
void Actual_Resize(int width, int height, const ViewportTransform& viewportTransform);
|
void Actual_Resize(int width, int height, const ViewportTransform& viewportTransform);
|
||||||
void Actual_Clear(float r, float g, float b);
|
void Actual_Clear(float r, float g, float b);
|
||||||
uint32_t Actual_Flip();
|
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);
|
uint32_t Actual_Download(SDL_Surface* target);
|
||||||
|
|||||||
@ -273,9 +273,9 @@ void DirectX9Renderer::Flip()
|
|||||||
Actual_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)
|
void DirectX9Renderer::SetDither(bool dither)
|
||||||
|
|||||||
@ -42,6 +42,13 @@ void GL11_DestroyTexture(GLuint texId)
|
|||||||
glDeleteTextures(1, &texId);
|
glDeleteTextures(1, &texId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GL11_GetMaxTextureSize()
|
||||||
|
{
|
||||||
|
GLint maxTextureSize = 0;
|
||||||
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||||
|
return maxTextureSize;
|
||||||
|
}
|
||||||
|
|
||||||
GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUi)
|
GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUi)
|
||||||
{
|
{
|
||||||
GLuint texId;
|
GLuint texId;
|
||||||
@ -285,9 +292,10 @@ void GL11_Clear(float r, float g, float b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GL11_Draw2DImage(
|
void GL11_Draw2DImage(
|
||||||
GLTextureCacheEntry& cache,
|
const GLTextureCacheEntry* cache,
|
||||||
const SDL_Rect& srcRect,
|
const SDL_Rect& srcRect,
|
||||||
const SDL_Rect& dstRect,
|
const SDL_Rect& dstRect,
|
||||||
|
const FColor& color,
|
||||||
float left,
|
float left,
|
||||||
float right,
|
float right,
|
||||||
float bottom,
|
float bottom,
|
||||||
@ -296,6 +304,7 @@ void GL11_Draw2DImage(
|
|||||||
{
|
{
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
|
glShadeModel(GL_FLAT);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@ -306,17 +315,28 @@ void GL11_Draw2DImage(
|
|||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
glDisable(GL_LIGHTING);
|
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);
|
float u1 = 0;
|
||||||
glBindTexture(GL_TEXTURE_2D, cache.glTextureId);
|
float v1 = 0;
|
||||||
glEnable(GL_BLEND);
|
float u2 = 0;
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
float v2 = 0;
|
||||||
|
|
||||||
float u1 = srcRect.x / cache.width;
|
if (cache) {
|
||||||
float v1 = srcRect.y / cache.height;
|
glEnable(GL_TEXTURE_2D);
|
||||||
float u2 = (srcRect.x + srcRect.w) / cache.width;
|
glBindTexture(GL_TEXTURE_2D, cache->glTextureId);
|
||||||
float v2 = (srcRect.y + srcRect.h) / cache.height;
|
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 x1 = (float) dstRect.x;
|
||||||
float y1 = (float) dstRect.y;
|
float y1 = (float) dstRect.y;
|
||||||
|
|||||||
@ -64,6 +64,7 @@ struct GLMeshCacheEntry {
|
|||||||
void GL11_InitState();
|
void GL11_InitState();
|
||||||
void GL11_LoadExtensions();
|
void GL11_LoadExtensions();
|
||||||
void GL11_DestroyTexture(GLuint texId);
|
void GL11_DestroyTexture(GLuint texId);
|
||||||
|
int GL11_GetMaxTextureSize();
|
||||||
GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUI);
|
GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUI);
|
||||||
void GL11_UploadMesh(GLMeshCacheEntry& cache, bool hasTexture);
|
void GL11_UploadMesh(GLMeshCacheEntry& cache, bool hasTexture);
|
||||||
void GL11_DestroyMesh(GLMeshCacheEntry& cache);
|
void GL11_DestroyMesh(GLMeshCacheEntry& cache);
|
||||||
@ -79,9 +80,10 @@ void GL11_SubmitDraw(
|
|||||||
void GL11_Resize(int width, int height);
|
void GL11_Resize(int width, int height);
|
||||||
void GL11_Clear(float r, float g, float b);
|
void GL11_Clear(float r, float g, float b);
|
||||||
void GL11_Draw2DImage(
|
void GL11_Draw2DImage(
|
||||||
GLTextureCacheEntry& cache,
|
const GLTextureCacheEntry* cache,
|
||||||
const SDL_Rect& srcRect,
|
const SDL_Rect& srcRect,
|
||||||
const SDL_Rect& dstRect,
|
const SDL_Rect& dstRect,
|
||||||
|
const FColor& color,
|
||||||
float left,
|
float left,
|
||||||
float right,
|
float right,
|
||||||
float bottom,
|
float bottom,
|
||||||
|
|||||||
@ -132,10 +132,21 @@ static Uint32 UploadTextureData(SDL_Surface* src, bool useNPOT, bool isUi)
|
|||||||
|
|
||||||
SDL_Surface* finalSurface = working;
|
SDL_Surface* finalSurface = working;
|
||||||
|
|
||||||
int newW = NextPowerOfTwo(working->w);
|
int newW = working->w;
|
||||||
int newH = NextPowerOfTwo(working->h);
|
int newH = working->h;
|
||||||
|
if (!useNPOT) {
|
||||||
|
newW = NextPowerOfTwo(newW);
|
||||||
|
newH = NextPowerOfTwo(newH);
|
||||||
|
}
|
||||||
|
int max = GL11_GetMaxTextureSize();
|
||||||
|
if (newW > max) {
|
||||||
|
newW = max;
|
||||||
|
}
|
||||||
|
if (newH > max) {
|
||||||
|
newH = max;
|
||||||
|
}
|
||||||
|
|
||||||
if (!useNPOT && (newW != working->w || newH != working->h)) {
|
if (newW != working->w || newH != working->h) {
|
||||||
SDL_Surface* resized = SDL_CreateSurface(newW, newH, working->format);
|
SDL_Surface* resized = SDL_CreateSurface(newW, newH, working->format);
|
||||||
if (!resized) {
|
if (!resized) {
|
||||||
SDL_Log("SDL_CreateSurface (resize) failed: %s", SDL_GetError());
|
SDL_Log("SDL_CreateSurface (resize) failed: %s", SDL_GetError());
|
||||||
@ -372,7 +383,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;
|
m_dirty = true;
|
||||||
|
|
||||||
@ -381,7 +392,12 @@ void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con
|
|||||||
float top = -m_viewportTransform.offsetY / m_viewportTransform.scale;
|
float top = -m_viewportTransform.offsetY / m_viewportTransform.scale;
|
||||||
float bottom = (m_height - 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)
|
void OpenGL1Renderer::SetDither(bool dither)
|
||||||
|
|||||||
@ -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;
|
m_dirty = true;
|
||||||
|
|
||||||
@ -607,25 +607,37 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c
|
|||||||
|
|
||||||
glUseProgram(m_shaderProgram);
|
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};
|
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][1], 1, blank);
|
||||||
glUniform4fv(u_lightLocs[0][2], 1, blank);
|
glUniform4fv(u_lightLocs[0][2], 1, blank);
|
||||||
glUniform1i(m_lightCountLoc, 1);
|
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);
|
glUniform1f(m_shinLoc, 0.0f);
|
||||||
|
|
||||||
const GLES2TextureCacheEntry& texture = m_textures[textureId];
|
SDL_Rect expandedDstRect;
|
||||||
float scaleX = static_cast<float>(dstRect.w) / srcRect.w;
|
if (textureId != NO_TEXTURE_ID) {
|
||||||
float scaleY = static_cast<float>(dstRect.h) / srcRect.h;
|
const GLES2TextureCacheEntry& texture = m_textures[textureId];
|
||||||
SDL_Rect expandedDstRect = {
|
float scaleX = static_cast<float>(dstRect.w) / srcRect.w;
|
||||||
static_cast<int>(std::round(dstRect.x - srcRect.x * scaleX)),
|
float scaleY = static_cast<float>(dstRect.h) / srcRect.h;
|
||||||
static_cast<int>(std::round(dstRect.y - srcRect.y * scaleY)),
|
expandedDstRect = {
|
||||||
static_cast<int>(std::round(texture.width * scaleX)),
|
static_cast<int>(std::round(dstRect.x - srcRect.x * scaleX)),
|
||||||
static_cast<int>(std::round(texture.height * scaleY))
|
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;
|
D3DRMMATRIX4D modelView, projection;
|
||||||
Create2DTransformMatrix(
|
Create2DTransformMatrix(
|
||||||
@ -645,11 +657,6 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c
|
|||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
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);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glScissor(
|
glScissor(
|
||||||
static_cast<int>(std::round(dstRect.x * m_viewportTransform.scale + m_viewportTransform.offsetX)),
|
static_cast<int>(std::round(dstRect.x * m_viewportTransform.scale + m_viewportTransform.offsetX)),
|
||||||
|
|||||||
@ -884,24 +884,37 @@ void Direct3DRMSDL3GPURenderer::Flip()
|
|||||||
m_cmdbuf = nullptr;
|
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) {
|
if (!m_renderPass) {
|
||||||
StartRenderPass(0, 0, 0, false);
|
StartRenderPass(0, 0, 0, false);
|
||||||
}
|
}
|
||||||
SDL_BindGPUGraphicsPipeline(m_renderPass, m_uiPipeline);
|
SDL_BindGPUGraphicsPipeline(m_renderPass, m_uiPipeline);
|
||||||
|
|
||||||
const SDL3TextureCache& tex = m_textures[textureId];
|
SDL_GPUTexture* tex;
|
||||||
|
SDL_Rect expandedDstRect;
|
||||||
auto surface = static_cast<DirectDrawSurfaceImpl*>(tex.texture->m_surface);
|
if (textureId == NO_TEXTURE_ID) {
|
||||||
float scaleX = static_cast<float>(dstRect.w) / srcRect.w;
|
expandedDstRect = dstRect;
|
||||||
float scaleY = static_cast<float>(dstRect.h) / srcRect.h;
|
tex = m_dummyTexture;
|
||||||
SDL_Rect expandedDstRect = {
|
}
|
||||||
static_cast<int>(std::round(dstRect.x - srcRect.x * scaleX)),
|
else {
|
||||||
static_cast<int>(std::round(dstRect.y - srcRect.y * scaleY)),
|
SDL3TextureCache& cache = m_textures[textureId];
|
||||||
static_cast<int>(std::round(static_cast<float>(surface->m_surface->w) * scaleX)),
|
tex = cache.gpuTexture;
|
||||||
static_cast<int>(std::round(static_cast<float>(surface->m_surface->h) * scaleY)),
|
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(
|
Create2DTransformMatrix(
|
||||||
expandedDstRect,
|
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};
|
SceneLight fullBright = {{1, 1, 1, 1}, {0, 0, 0}, 0, {0, 0, 0}, 0};
|
||||||
memcpy(&m_fragmentShadingData.lights, &fullBright, sizeof(SceneLight));
|
memcpy(&m_fragmentShadingData.lights, &fullBright, sizeof(SceneLight));
|
||||||
m_fragmentShadingData.lightCount = 1;
|
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.shininess = 0.0f;
|
||||||
m_fragmentShadingData.useTexture = 1;
|
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_BindGPUFragmentSamplers(m_renderPass, 0, &samplerBinding, 1);
|
||||||
SDL_PushGPUVertexUniformData(m_cmdbuf, 0, &m_uniforms, sizeof(m_uniforms));
|
SDL_PushGPUVertexUniformData(m_cmdbuf, 0, &m_uniforms, sizeof(m_uniforms));
|
||||||
SDL_PushGPUFragmentUniformData(m_cmdbuf, 0, &m_fragmentShadingData, sizeof(m_fragmentShadingData));
|
SDL_PushGPUFragmentUniformData(m_cmdbuf, 0, &m_fragmentShadingData, sizeof(m_fragmentShadingData));
|
||||||
|
|||||||
@ -774,16 +774,35 @@ void Direct3DRMSoftwareRenderer::Flip()
|
|||||||
SDL_RenderPresent(m_renderer);
|
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 = {
|
SDL_Rect centeredRect = {
|
||||||
static_cast<int>(dstRect.x * m_viewportTransform.scale + m_viewportTransform.offsetX),
|
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.y * m_viewportTransform.scale + m_viewportTransform.offsetY),
|
||||||
static_cast<int>(dstRect.w * m_viewportTransform.scale),
|
static_cast<int>(dstRect.w * m_viewportTransform.scale),
|
||||||
static_cast<int>(dstRect.h * 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, ¢eredRect, sdlColor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface* surface = m_textures[textureId].cached;
|
||||||
|
SDL_UnlockSurface(surface);
|
||||||
SDL_BlitSurfaceScaled(surface, &srcRect, m_renderedImage, ¢eredRect, SDL_SCALEMODE_LINEAR);
|
SDL_BlitSurfaceScaled(surface, &srcRect, m_renderedImage, ¢eredRect, SDL_SCALEMODE_LINEAR);
|
||||||
SDL_LockSurface(surface);
|
SDL_LockSurface(surface);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,16 +48,32 @@ HRESULT FrameBufferImpl::Blt(
|
|||||||
if (!DDRenderer) {
|
if (!DDRenderer) {
|
||||||
return DDERR_GENERIC;
|
return DDERR_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamic_cast<FrameBufferImpl*>(lpDDSrcSurface) == this) {
|
if (dynamic_cast<FrameBufferImpl*>(lpDDSrcSurface) == this) {
|
||||||
return Flip(nullptr, DDFLIP_WAIT);
|
return Flip(nullptr, DDFLIP_WAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dwFlags & DDBLT_COLORFILL) == DDBLT_COLORFILL) {
|
if ((dwFlags & DDBLT_COLORFILL) == DDBLT_COLORFILL) {
|
||||||
|
Uint8 a = (lpDDBltFx->dwFillColor >> 24) & 0xFF;
|
||||||
Uint8 r = (lpDDBltFx->dwFillColor >> 16) & 0xFF;
|
Uint8 r = (lpDDBltFx->dwFillColor >> 16) & 0xFF;
|
||||||
Uint8 g = (lpDDBltFx->dwFillColor >> 8) & 0xFF;
|
Uint8 g = (lpDDBltFx->dwFillColor >> 8) & 0xFF;
|
||||||
Uint8 b = lpDDBltFx->dwFillColor & 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;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto surface = static_cast<DirectDrawSurfaceImpl*>(lpDDSrcSurface);
|
auto surface = static_cast<DirectDrawSurfaceImpl*>(lpDDSrcSurface);
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
return DDERR_GENERIC;
|
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};
|
lpSrcRect ? ConvertRect(lpSrcRect) : SDL_Rect{0, 0, surface->m_surface->w, surface->m_surface->h};
|
||||||
SDL_Rect dstRect =
|
SDL_Rect dstRect =
|
||||||
lpDestRect ? ConvertRect(lpDestRect) : SDL_Rect{0, 0, (int) m_virtualWidth, (int) m_virtualHeight};
|
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;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ class Direct3DRMRenderer : public IDirect3DDevice2 {
|
|||||||
virtual void Resize(int width, int height, const ViewportTransform& viewportTransform) = 0;
|
virtual void Resize(int width, int height, const ViewportTransform& viewportTransform) = 0;
|
||||||
virtual void Clear(float r, float g, float b) = 0;
|
virtual void Clear(float r, float g, float b) = 0;
|
||||||
virtual void Flip() = 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 Download(SDL_Surface* target) = 0;
|
||||||
virtual void SetDither(bool dither) = 0;
|
virtual void SetDither(bool dither) = 0;
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,7 @@ class Citro3DRenderer : public Direct3DRMRenderer {
|
|||||||
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
||||||
void Clear(float r, float g, float b) override;
|
void Clear(float r, float g, float b) override;
|
||||||
void Flip() 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 Download(SDL_Surface* target) override;
|
||||||
void SetDither(bool dither) override;
|
void SetDither(bool dither) override;
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@ class DirectX9Renderer : public Direct3DRMRenderer {
|
|||||||
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
||||||
void Clear(float r, float g, float b) override;
|
void Clear(float r, float g, float b) override;
|
||||||
void Flip() 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 Download(SDL_Surface* target) override;
|
||||||
void SetDither(bool dither) override;
|
void SetDither(bool dither) override;
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@ class OpenGL1Renderer : public Direct3DRMRenderer {
|
|||||||
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
||||||
void Clear(float r, float g, float b) override;
|
void Clear(float r, float g, float b) override;
|
||||||
void Flip() 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 Download(SDL_Surface* target) override;
|
||||||
void SetDither(bool dither) override;
|
void SetDither(bool dither) override;
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,7 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
|
|||||||
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
||||||
void Clear(float r, float g, float b) override;
|
void Clear(float r, float g, float b) override;
|
||||||
void Flip() 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 Download(SDL_Surface* target) override;
|
||||||
void SetDither(bool dither) override;
|
void SetDither(bool dither) override;
|
||||||
|
|
||||||
|
|||||||
@ -65,7 +65,7 @@ class Direct3DRMSDL3GPURenderer : public Direct3DRMRenderer {
|
|||||||
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
||||||
void Clear(float r, float g, float b) override;
|
void Clear(float r, float g, float b) override;
|
||||||
void Flip() 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 Download(SDL_Surface* target) override;
|
||||||
void SetDither(bool dither) override;
|
void SetDither(bool dither) override;
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ class Direct3DRMSoftwareRenderer : public Direct3DRMRenderer {
|
|||||||
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
||||||
void Clear(float r, float g, float b) override;
|
void Clear(float r, float g, float b) override;
|
||||||
void Flip() 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 Download(SDL_Surface* target) override;
|
||||||
void SetDither(bool dither) override;
|
void SetDither(bool dither) override;
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,7 @@ Keywords[ru]=LEGO;lego;Остров LEGO
|
|||||||
Keywords[uk_UA]=LEGO;lego;LEGO острів
|
Keywords[uk_UA]=LEGO;lego;LEGO острів
|
||||||
|
|
||||||
SingleMainWindow=true
|
SingleMainWindow=true
|
||||||
|
StartupWMClass=isle
|
||||||
|
|
||||||
TryExec=isle
|
TryExec=isle
|
||||||
Exec=isle
|
Exec=isle
|
||||||
|
|||||||
75
tools/curpng2h.py
Executable file
75
tools/curpng2h.py
Executable file
@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import itertools
|
||||||
|
from PIL import Image
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def encode_cursor(image_path: Path):
|
||||||
|
img = Image.open(image_path).convert("RGBA")
|
||||||
|
width, height = img.size
|
||||||
|
pixels = img.load()
|
||||||
|
|
||||||
|
num_pixels = width * height
|
||||||
|
num_bytes = (num_pixels + 7) // 8
|
||||||
|
|
||||||
|
data = bytearray(num_bytes)
|
||||||
|
mask = bytearray(num_bytes)
|
||||||
|
|
||||||
|
for y in range(height):
|
||||||
|
for x in range(width):
|
||||||
|
i = y * width + x
|
||||||
|
byte_index = i // 8
|
||||||
|
bit_offset = 7 - (i % 8)
|
||||||
|
|
||||||
|
r, g, b, a = pixels[x, y]
|
||||||
|
|
||||||
|
if a >= 128:
|
||||||
|
mask[byte_index] |= 1 << bit_offset # opaque
|
||||||
|
lum = int(0.299 * r + 0.587 * g + 0.114 * b)
|
||||||
|
if lum < 128:
|
||||||
|
data[byte_index] |= 1 << bit_offset # black pixel
|
||||||
|
|
||||||
|
return data, mask, width, height
|
||||||
|
|
||||||
|
|
||||||
|
def to_c_array(name, data):
|
||||||
|
lines = []
|
||||||
|
for rowdata in itertools.batched(data, 12):
|
||||||
|
lines.append(", ".join(f"0x{byte:02X}" for byte in rowdata) + ",")
|
||||||
|
array_str = "\n ".join(lines)
|
||||||
|
return f"static const unsigned char {name}[] = {{\n {array_str}\n}};\n"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(allow_abbrev=False)
|
||||||
|
parser.add_argument("inputs", nargs="+", help="PNG images", type=Path)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
input_files: list[Path] = args.inputs
|
||||||
|
|
||||||
|
for input_file in input_files:
|
||||||
|
data, mask, width, height = encode_cursor(input_file)
|
||||||
|
|
||||||
|
input_file_name = input_file.stem
|
||||||
|
output_file = input_file.with_name(f"{input_file_name}_bmp.h")
|
||||||
|
|
||||||
|
with output_file.open("w", newline="\n") as f:
|
||||||
|
f.write(f"#pragma once\n\n")
|
||||||
|
f.write(f"// Generated from {input_file}\n")
|
||||||
|
f.write(f"// Dimensions: {width}x{height}\n")
|
||||||
|
f.write("// This file is auto-generated, do not edit it.\n\n")
|
||||||
|
f.write(f'#include "cursor.h"\n\n')
|
||||||
|
f.write(to_c_array(f"{input_file_name}_data", data))
|
||||||
|
f.write("\n")
|
||||||
|
f.write(to_c_array(f"{input_file_name}_mask", mask))
|
||||||
|
f.write("\n")
|
||||||
|
f.write(
|
||||||
|
f"static const CursorBitmap {input_file_name}_cursor = {'{'} {width}, {height}, {input_file_name}_data, {input_file_name}_mask {'}'};\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Written {output_file} with cursor data.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Loading…
Reference in New Issue
Block a user