From dcbcf7a8a408c4fc3c56c45a84c18bb9900d00e4 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 23 Dec 2024 18:02:08 +0100 Subject: [PATCH 1/5] Implement MxDisplaySurface::VTable0x34 --- LEGO1/omni/include/mxdisplaysurface.h | 14 ++--- LEGO1/omni/src/video/mxdisplaysurface.cpp | 62 +++++++++++++++++++++-- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/LEGO1/omni/include/mxdisplaysurface.h b/LEGO1/omni/include/mxdisplaysurface.h index a6925e3d30..eb5d9ea3be 100644 --- a/LEGO1/omni/include/mxdisplaysurface.h +++ b/LEGO1/omni/include/mxdisplaysurface.h @@ -66,13 +66,13 @@ class MxDisplaySurface : public MxCore { MxS32 p_height, MxBool p_RLE ); // vtable+0x30 - virtual undefined4 VTable0x34( - undefined4, - undefined4, - undefined4, - undefined4, - undefined4, - undefined4 + virtual void VTable0x34( + MxU8* p_pixels, + MxS32 p_bpp, + MxS32 p_width, + MxS32 p_height, + MxS32 p_x, + MxS32 p_y ); // vtable+0x34 virtual void Display( MxS32 p_left, diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index 2d179d0182..d88038bd5c 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -739,10 +739,66 @@ void MxDisplaySurface::DrawTransparentRLE( } } -// STUB: LEGO1 0x100bb850 -undefined4 MxDisplaySurface::VTable0x34(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) +// FUNCTION: LEGO1 0x100bb850 +void MxDisplaySurface::VTable0x34(MxU8 *p_pixels, MxS32 p_bpp, MxS32 p_width, MxS32 p_height, MxS32 p_x, MxS32 p_y) { - return 0; + DDSURFACEDESC surfaceDesc; + memset(&surfaceDesc, 0, sizeof(surfaceDesc)); + surfaceDesc.dwSize = sizeof(surfaceDesc); + HRESULT result = m_ddSurface2->Lock(NULL, &surfaceDesc, DDLOCK_WAIT, NULL); + if (result == DDERR_SURFACELOST) { + m_ddSurface2->Restore(); + result = m_ddSurface2->Lock(NULL, &surfaceDesc, DDLOCK_WAIT, NULL); + } + if (result != DD_OK) { + return; + } + int dst_bitcount = m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount; + switch (dst_bitcount) { + case 8: + if (p_bpp == 16) { + // BUG: should go to end of function and unlock m_ddSurface2 + return; + } else { + MxU8 *dst = (MxU8 *)surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + p_x; + MxU8 *src = p_pixels; + while (p_height != 0) { + p_height--; + memcpy(dst, src, p_width); + src += p_width; + dst += surfaceDesc.lPitch; + } + } + break; + case 16: + switch (p_bpp) { + case 16: { + MxU8 *dst = (MxU8 *)surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + 2 * p_x; + MxU8 *src = p_pixels; + while (p_height != 0) { + p_height--; + memcpy(dst, src, 2 * p_width); + src += 2 * p_width; + dst += surfaceDesc.lPitch; + } + break; + } + case 8: { + MxU8 *dst = (MxU8 *)surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + 2 * p_x; + MxU8 *src = p_pixels; + for (MxS32 i = 0; i < p_height; src += p_width, dst += surfaceDesc.lPitch, i++) { + for (MxS32 j = 0; j < p_width; dst += 2, src += 1, j++) { + *(MxU16 *) dst = m_16bitPal[*src]; + } + } + break; + } + default: + break; + } + break; + } + m_ddSurface2->Unlock(surfaceDesc.lpSurface); } // FUNCTION: LEGO1 0x100bba50 From 5994df1407f55a024d0ac69ef9278f8bb00635f4 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 23 Dec 2024 11:05:09 -0700 Subject: [PATCH 2/5] Match --- LEGO1/omni/src/video/mxdisplaysurface.cpp | 126 ++++++++++++---------- 1 file changed, 68 insertions(+), 58 deletions(-) diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index d88038bd5c..d08322ce70 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -1,6 +1,7 @@ #include "mxdisplaysurface.h" #include "mxbitmap.h" +#include "mxdebug.h" #include "mxmisc.h" #include "mxomni.h" #include "mxpalette.h" @@ -740,65 +741,74 @@ void MxDisplaySurface::DrawTransparentRLE( } // FUNCTION: LEGO1 0x100bb850 -void MxDisplaySurface::VTable0x34(MxU8 *p_pixels, MxS32 p_bpp, MxS32 p_width, MxS32 p_height, MxS32 p_x, MxS32 p_y) +// 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, NULL); - if (result == DDERR_SURFACELOST) { - m_ddSurface2->Restore(); - result = m_ddSurface2->Lock(NULL, &surfaceDesc, DDLOCK_WAIT, NULL); - } - if (result != DD_OK) { - return; - } - int dst_bitcount = m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount; - switch (dst_bitcount) { - case 8: - if (p_bpp == 16) { - // BUG: should go to end of function and unlock m_ddSurface2 - return; - } else { - MxU8 *dst = (MxU8 *)surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + p_x; - MxU8 *src = p_pixels; - while (p_height != 0) { - p_height--; - memcpy(dst, src, p_width); - src += p_width; - dst += surfaceDesc.lPitch; - } - } - break; - case 16: - switch (p_bpp) { - case 16: { - MxU8 *dst = (MxU8 *)surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + 2 * p_x; - MxU8 *src = p_pixels; - while (p_height != 0) { - p_height--; - memcpy(dst, src, 2 * p_width); - src += 2 * p_width; - dst += surfaceDesc.lPitch; - } - break; - } - case 8: { - MxU8 *dst = (MxU8 *)surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + 2 * p_x; - MxU8 *src = p_pixels; - for (MxS32 i = 0; i < p_height; src += p_width, dst += surfaceDesc.lPitch, i++) { - for (MxS32 j = 0; j < p_width; dst += 2, src += 1, j++) { - *(MxU16 *) dst = m_16bitPal[*src]; - } - } - break; - } - default: - break; - } - break; - } - m_ddSurface2->Unlock(surfaceDesc.lpSurface); + DDSURFACEDESC surfaceDesc; + memset(&surfaceDesc, 0, sizeof(surfaceDesc)); + surfaceDesc.dwSize = sizeof(surfaceDesc); + + HRESULT result = m_ddSurface2->Lock(NULL, &surfaceDesc, DDLOCK_WAIT, NULL); + + if (result == DDERR_SURFACELOST) { + m_ddSurface2->Restore(); + result = m_ddSurface2->Lock(NULL, &surfaceDesc, DDLOCK_WAIT, NULL); + } + + if (result == DD_OK) { + MxU8* pixels = p_pixels; + + switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) { + case 8: { + if (p_bpp == 16) { + MxTrace("16 bit source to 8 bit display NOT_IMPLEMENTED"); + assert(0); + return; + } + + MxU8* dst = (MxU8*) surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + p_x; + MxLong stride = p_width; + MxLong length = surfaceDesc.lPitch; + + while (p_height--) { + memcpy(dst, pixels, p_width); + pixels += stride; + dst += length; + } + break; + } + case 16: { + if (p_bpp == 16) { + MxU8* dst = (MxU8*) surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + p_x; + MxLong stride = p_width * 2; + MxLong length = surfaceDesc.lPitch; + + while (p_height--) { + memcpy(dst, pixels, 2 * p_width); + pixels += stride; + dst += length; + } + } + else if (p_bpp == 8) { + MxU8* dst = (MxU8*) surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + 2 * p_x; + MxLong stride = p_width * 2; + MxLong length = -2 * p_width + surfaceDesc.lPitch; + + for (MxS32 i = 0; i < p_height; i++) { + for (MxS32 j = 0; j < p_width; j++) { + *(MxU16*) dst = m_16bitPal[*pixels++]; + dst += 2; + } + + pixels += stride; + dst += length; + } + } + } + } + + m_ddSurface2->Unlock(surfaceDesc.lpSurface); + } } // FUNCTION: LEGO1 0x100bba50 From 3d4e6cbc62bc4e8e63309ca1cb0099d70e245f2e Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 23 Dec 2024 11:07:20 -0700 Subject: [PATCH 3/5] Remove function count since we got them all --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 61736b1301..e4f26c955f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -139,7 +139,7 @@ jobs: run: | reccmp-reccmp -S CONFIGPROGRESS.SVG --svg-icon assets/config.png --target CONFIG | tee CONFIGPROGRESS.TXT reccmp-reccmp -S ISLEPROGRESS.SVG --svg-icon assets/isle.png --target ISLE | tee ISLEPROGRESS.TXT - reccmp-reccmp -S LEGO1PROGRESS.SVG -T 4358 --svg-icon assets/lego1.png --target LEGO1 | tee LEGO1PROGRESS.TXT + reccmp-reccmp -S LEGO1PROGRESS.SVG --svg-icon assets/lego1.png --target LEGO1 | tee LEGO1PROGRESS.TXT - name: Compare Accuracy With Current Master shell: bash From 4799cf4be7b9f90982ee3d2910ac9822f0f5fe01 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 23 Dec 2024 11:10:55 -0700 Subject: [PATCH 4/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2240ae0920..539a4cf7f5 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is a **work-in-progress** decompilation of LEGO Island (Version 1.1, Englis -Currently, `ISLE.EXE` is completely decompiled and is functionally identical to the original, while `LEGO1.DLL` is complete in terms of gameplay features. However, work is still ongoing to improve the accuracy, naming, documentation, and structure of the source code. While there may still be unresolved bugs that are not present in retail, the game should be fully playable with the binaries derived from this source code. +Both `ISLE.EXE` and `LEGO1.DLL` are completely decompiled and, to the best of our knowledge, are functionally identical to the originals. However, work is still ongoing to improve the accuracy, naming, documentation, and structure of the source code. While there may still be unresolved bugs that are not present in retail, the game should be fully playable with the binaries derived from this source code. Due to various complexities with regard to the compiler, these binaries are not a byte-for-byte match of the original executables. We remain hopeful that this can be resolved at some point. From 4bb2cde31f751dafe0b40adb6b4080b81c9c3fe1 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 23 Dec 2024 11:12:24 -0700 Subject: [PATCH 5/5] Remove emphasis on work-in-progress --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 539a4cf7f5..97f63139f8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [Development Vlog](https://www.youtube.com/playlist?list=PLbpl-gZkNl2COf_bB6cfgTapD5WduAfPz) | [Contributing](/CONTRIBUTING.md) | [Matrix](https://matrix.to/#/#isledecomp:matrix.org) | [Forums](https://forum.mattkc.com/viewforum.php?f=1) | [Patreon](https://www.patreon.com/mattkc) -This is a **work-in-progress** decompilation of LEGO Island (Version 1.1, English). It aims to be as accurate as possible, matching the recompiled instructions to the original machine code as much as possible. The goal is to provide a workable codebase that can be modified, improved, and ported to other platforms later on. +This is a functionally complete decompilation of LEGO Island (Version 1.1, English). It aims to be as accurate as possible, matching the recompiled instructions to the original machine code as much as possible. The goal is to provide a workable codebase that can be modified, improved, and ported to other platforms later on. ## Status