🧑‍💻 fix: use CursorBitmap struct, handle every pixel format

This commit is contained in:
Helloyunho 2025-07-03 14:15:07 +09:00
parent e200f1ca3e
commit 31ea400f9b
No known key found for this signature in database
GPG Key ID: 6AFA210B0150BE47
7 changed files with 80 additions and 61 deletions

View File

@ -753,12 +753,7 @@ MxResult IsleApp::SetupWindow()
LegoOmni::GetInstance()->GetInputManager()->SetJoystickIndex(m_joystickIndex);
}
if (LegoOmni::GetInstance()->GetVideoManager() && g_isle->GetDrawCursor()) {
LegoOmni::GetInstance()->GetVideoManager()->SetCursorBitmap(
m_cursorCurrentBitmap->width,
m_cursorCurrentBitmap->height,
m_cursorCurrentBitmap->data,
m_cursorCurrentBitmap->mask
);
LegoOmni::GetInstance()->GetVideoManager()->SetCursorBitmap(m_cursorCurrentBitmap);
}
MxDirect3D* d3d = LegoOmni::GetInstance()->GetVideoManager()->GetDirect3D();
if (d3d) {
@ -1070,15 +1065,10 @@ void IsleApp::SetupCursor(Cursor p_cursor)
if (g_isle->GetDrawCursor()) {
if (m_cursorCurrentBitmap == NULL) {
VideoManager()->SetCursorBitmap(0, 0, NULL, NULL);
VideoManager()->SetCursorBitmap(NULL);
}
else {
VideoManager()->SetCursorBitmap(
m_cursorCurrentBitmap->width,
m_cursorCurrentBitmap->height,
m_cursorCurrentBitmap->data,
m_cursorCurrentBitmap->mask
);
VideoManager()->SetCursorBitmap(m_cursorCurrentBitmap);
}
}
else {

View File

@ -1,12 +1,12 @@
#ifndef ISLEAPP_H
#define ISLEAPP_H
#include "cursor.h"
#include "lego1_export.h"
#include "legoutils.h"
#include "mxtransitionmanager.h"
#include "mxtypes.h"
#include "mxvideoparam.h"
#include "res/cursor.h"
#include <SDL3/SDL.h>
#ifdef MINIWIN

View File

@ -1,6 +1,7 @@
#ifndef LEGOVIDEOMANAGER_H
#define LEGOVIDEOMANAGER_H
#include "cursor.h"
#include "decomp.h"
#include "lego1_export.h"
#include "legophonemelist.h"
@ -37,12 +38,7 @@ class LegoVideoManager : public MxVideoManager {
void EnableFullScreenMovie(MxBool p_enable);
LEGO1_EXPORT void EnableFullScreenMovie(MxBool p_enable, MxBool p_scale);
LEGO1_EXPORT void MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY);
LEGO1_EXPORT void SetCursorBitmap(
MxS32 p_width,
MxS32 p_height,
const MxU8* p_cursorBitmap,
const MxU8* p_cursorMask
);
LEGO1_EXPORT void SetCursorBitmap(const CursorBitmap* p_cursorBitmap);
void ToggleFPS(MxBool p_visible);
MxResult Tickle() override; // vtable+0x08

View File

@ -836,12 +836,7 @@ void LegoVideoManager::DrawTextToSurface32(
}
}
void LegoVideoManager::SetCursorBitmap(
MxS32 p_width,
MxS32 p_height,
const MxU8* p_cursorBitmap,
const MxU8* p_cursorMask
)
void LegoVideoManager::SetCursorBitmap(const CursorBitmap* p_cursorBitmap)
{
if (p_cursorBitmap == NULL) {
m_drawCursor = FALSE;
@ -855,10 +850,10 @@ void LegoVideoManager::SetCursorBitmap(
m_cursorRect.top = 0;
m_cursorRect.left = 0;
m_cursorRect.bottom = p_height;
m_cursorRect.right = p_width;
m_cursorRect.bottom = p_cursorBitmap->height;
m_cursorRect.right = p_cursorBitmap->width;
m_cursorSurface = MxDisplaySurface::CreateCursorSurface(p_width, p_height, p_cursorBitmap, p_cursorMask);
m_cursorSurface = MxDisplaySurface::CreateCursorSurface(p_cursorBitmap);
if (m_cursorSurface == NULL) {
m_drawCursor = FALSE;

View File

@ -1,6 +1,7 @@
#ifndef MXDISPLAYSURFACE_H
#define MXDISPLAYSURFACE_H
#include "cursor.h"
#include "decomp.h"
#include "mxcore.h"
#include "mxvideoparam.h"
@ -97,12 +98,7 @@ class MxDisplaySurface : public MxCore {
void ClearScreen();
static LPDIRECTDRAWSURFACE CreateCursorSurface();
static LPDIRECTDRAWSURFACE CreateCursorSurface(
MxS32 p_width,
MxS32 p_height,
const MxU8* p_cursorBitmap,
const MxU8* p_cursorMask
);
static LPDIRECTDRAWSURFACE CreateCursorSurface(const CursorBitmap* p_cursorBitmap);
static LPDIRECTDRAWSURFACE CopySurface(LPDIRECTDRAWSURFACE p_src);
LPDIRECTDRAWSURFACE GetDirectDrawSurface1() { return m_ddSurface1; }

View File

@ -1297,12 +1297,7 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::FUN_100bc8b0(MxS32 p_width, MxS32 p_height
return surface;
}
LPDIRECTDRAWSURFACE MxDisplaySurface::CreateCursorSurface(
MxS32 p_width,
MxS32 p_height,
const MxU8* p_cursorBitmap,
const MxU8* p_cursorMask
)
LPDIRECTDRAWSURFACE MxDisplaySurface::CreateCursorSurface(const CursorBitmap* p_cursorBitmap)
{
LPDIRECTDRAWSURFACE newSurface = NULL;
IDirectDraw* draw = MVideoManager()->GetDirectDraw();
@ -1316,12 +1311,10 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::CreateCursorSurface(
return NULL;
}
MxU32 whitePixel = RGB8888_CREATE(0xff, 0xff, 0xff, 0xff);
MxU32 blackPixel = RGB8888_CREATE(0, 0, 0, 0xff);
MxU32 transparentPixel = RGB8888_CREATE(0, 0, 0, 0);
MxS32 bytesPerPixel = ddsd.ddpfPixelFormat.dwRGBBitCount / 8;
ddsd.dwWidth = p_width;
ddsd.dwHeight = p_height;
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;
@ -1341,30 +1334,79 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::CreateCursorSurface(
goto done;
}
else {
MxU32* surface = (MxU32*) ddsd.lpSurface;
for (int y = 0; y < p_height; y++) {
for (int x = 0; x < p_width; x++) {
MxS32 bitIndex = y * p_width + x;
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_cursorMask[byteIndex] >> bitOffset) & 1;
MxBool isBlack = (p_cursorBitmap[byteIndex] >> bitOffset) & 1;
MxBool isOpaque = (p_cursorBitmap->mask[byteIndex] >> bitOffset) & 1;
MxBool isBlack = (p_cursorBitmap->data[byteIndex] >> bitOffset) & 1;
MxS32 pixel;
if (!isOpaque) {
pixel = transparentPixel;
}
else {
pixel = isBlack ? blackPixel : whitePixel;
}
switch (bytesPerPixel) {
case 1: {
MxU8* surface = (MxU8*) ddsd.lpSurface;
surface[x + y * p_width] = pixel;
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;
}