Browse Source

Fix engine (objects always being lit) (#132)

Also refactored readme
pull/4/head
galaxyhaxz 8 years ago committed by GitHub
parent
commit
8f50c57141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 106
      README.md
  2. 184
      Source/engine.cpp
  3. 4
      Source/engine.h
  4. 0
      Support/CONTRIBUTING.md
  5. 25
      Support/TODO.md
  6. 25
      TODO

106
README.md

@ -1,8 +1,7 @@
[![Build Status](https://travis-ci.org/diasurgical/devilution.svg?branch=master)](https://travis-ci.org/diasurgical/devilution)
[![Build status](https://ci.appveyor.com/api/projects/status/ssk0xjhoka1uu940?svg=true)](https://ci.appveyor.com/project/galaxyhaxz/devilution)
### [Devilution Development & Xyinn Network Discord](https://discord.gg/3DD6ZVQ)
[Discord](https://discord.gg/3DD6ZVQ)
# Devilution
Diablo devolved - magic behind the 1996 computer game
@ -10,69 +9,66 @@ Diablo devolved - magic behind the 1996 computer game
Reverse engineered by GalaXyHaXz in 2018
# Introduction
Diablo was everything but loved by Blizzard. The last update to the game was in 2001, and Blizzard stopped supporting/selling it altogether a few years ago. I took up a mission to fix this problem. Diablo was a game I played extensively as a teenager; but as time passed, it became difficult to run the game on newer hardware. The lack of new content also took away from the re-playability. The ideal solution would be to modernize the source, but reversing the whole game initially sounded impossible.
Thankfully, there was a little oversight in 1998. Blizzard gave Diablo's source code to two developers: Synergestic Software (to create an expansion), and Climax Studios (to create a Playstation port). Now Sony of Japan has long been known for letting things slide in their QA department. Anything from prototypes to full source code leaks (Beatmania), and Diablo was no exception. A symbolic file was accidentally left on the Japanese port, which contained a layout of everything in the game. This includes functions, data, types, and more! A beta version of the port also leaked, which contained yet another one of these files.
While most titles from Blizzard receive years of love and support, Diablo stayed in the shadows. Abandoned in favor of a sequel, it remained full of bugs and unfinished potential. The game was last patched in 2001 before being discontinued altogether, a problem I wanted to fix. I played Diablo extensively as a teenager, but as time passed it became difficult to run the game on newer hardware. The lack of many improvements found in the sequel also kept it from aging well. At first the game appeared to be a lost cause, but thankfully a little oversight in 1997 made it not so.
To top it all off, a debug build of the PC version is contained right there on your Diablo disc! Hidden in `DIABDAT.MPQ -> D1221A.MPQ -> DIABLO.EXE`. This build contains debug tools not found in the retail game, and many assert strings giving away code information. Combining these aspects not only makes reversing the game much easier, but it makes it far more accurate. File names, function names, and even line numbers will be fairly close to the real deal.
With Diablo's development team moving on the source code was given to **Synergestic Software** to handle the expansion. Less known however is that it was also given to **Climax Studios** to create a PlayStation port. Now Sony has long been known for letting things slide; _especially_ in Japan. Anything from leaking prototypes to full source code and Diablo was no exception. Symbolic information was accidentally left on the Japanese port. Normally used for debugging, a symbol file contains a map of everything generated during compile time. This includes file names, functions, structures, variables, and more! To top it all off a special build is hidden on the PC release in `DIABDAT.MPQ -> D1221A.MPQ -> DIABLO.EXE`! This build contains debug tools and assert strings further giving away code information.
After four months of hard work, I present to you Devilution! Instead of seeing how Diablo evolved, we'll see it devolved!
After months of peicing these mistakes together, Devilution was born. I present to you a reconstructed form of Diablo's original source code! Once more shall the heroes of Sanctuary return to the depths below!
# Purpose
Having the source code makes things much easier to maintain. For years mod-makers had to rely on tedious code editing and memory injection. A few even went even further and reversed a good chunk of the game (such as Belzebub/The Hell). The problem is that they never released their sources. Usually being a one-man job, they move on with their lives inevitably due to the amount of time/work required or lack of interest. This leaves people with a half-finished mod; one which had countless hours put into it, but left full of bugs and unfinished potential. So we're back to square one. Devilution aims to fix this, by making the source code of Diablo freely available to all.
Having the source code makes Diablo much easier to update and maintain. For years mod-makers had to rely on tedious code editing and memory injection. A few even went further and reversed most or all of the game. The problem is that they rarely shared their work. Usually being a one-person job, they move on with their lives due to the amount of time required or lack of interest. This brings us back to square one having to do countless hours of work all over again. Devilution aims to fix this by finally making the source code open to the community.
The goal of Devilution itself is to recreate the original source code as accurately as possible, in order to ensure that everything is preserved. This goes as far as bugs and badly written code in the original game. However, it becomes a solid base for developers to work with; making it much easier than before to update, fix, and port the game to other platforms.
In order to ensure that everything is preserved, Devilution keeps everything as it was originally designed. This goes as far as bugs and badly written code in the original game. With that it serves as a base for developers to work with making it much easier then before to update, fix, and port the game to other platforms.
As a side goal, Devilution helps document the unused and cut content from the final game. Development of Diablo was rushed near the end--many ideas were scrapped and Multiplayer was quickly hacked in. By examining the source, we can see various quirks of planned development.
As a side goal Devilution tries to document the unused and cut content from the final game. Development of Diablo was rushed near the end--many ideas were scrapped and Multiplayer was quickly hacked in. By examining the source, we can see various quirks of planned development.
# Compiling
Development of Diablo began around the time Windows 95 released, for which it was optimized. The compiler used was Microsoft Visual C++ 4.20, which was upgraded to 5.10 in later patches ([ref: spreadsheet](Support/surgery.xls)). Compatibility with these tools is retained to help ensure the reversal is as accurate as possible. There are also Makefiles provided to compile with modern tools as well.
Diablo was developed on Windows 95 using Visual C++ 4.20 and later 5.10 for newer patches. Devilution is optimized for the same tools originally used but is also compatible with modern setups.
Building with Visual C++ 5.10
- Make sure Service Pack 3 is installed in order to update the linker from 5.00 -> 5.10! Newer versions of Visual Studio work as well, but will upgrade the project.
- Open the project workspace `Diablo.dsw` and select `Build Diablo.exe`. This will build all dependencies and only takes a few seconds.
### Building with Visual C++ 4/5/6
- Open the project workspace `Diablo.dsw`, choose `Debug` or `Release`, and then `Build Diablo.exe`.
Building with modern version of Visual Studio
To build a binary as close as possible to the original, use [Visual C++ 5](https://winworldpc.com/product/visual-c/5x) upgraded to [Service Pack 3](http://www.mediafire.com/file/jw4j4sd5dnzze4p/VS97SP3.zip).
The DEP tweak is already included in the project as default for the .sln until we can figure out the root cause.
- Make sure to disable Data Exection Prevention: Configuration options -> Linker -> Advanced -> Data Execution Prevention (DEP).
- Set this value to: No (/NXCOMPAT: NO).
### Building with Visual Studio 2010-2017
- Open the project solution `Diablo.sln`, choose `Debug` or `Release`, and then `Build Solution`.
- Storm.dll uses dynamic compilation to improve rendering performance but fails to mark the resulting memory page as executable, leading to a protection fault when trying to draw.
Make sure to disable Data Exection Prevention. `Storm.dll` uses dynamic compilation to improve rendering performance but fails to mark the resulting memory page as executable, leading to a protection fault when trying to draw.
- Configuration options -> Linker -> Advanced -> Data Execution Prevention (DEP).
- Set this value to: No (/NXCOMPAT: NO).
You will also need the following dependencies installed if you are using Visual Studio 2017.
Make sure to enable these when installing (or modify your installation):
- Requires "Windows 8.1 SDK" (Target Platform)
- Requires "Visual C++ MFC for x86 and x64" (For afxres.h)
- Requires "Windows Universal CRT SDK" (For ctype.h)
Devilution for VS 2017 compilation is currently targetting Windows 8.1 SDK.
Building with MinGW(32/64)
- Ensure that the MinGW binary paths have been added to the command line. On Windows, you would usually type: `set PATH=C:\mingw\bin;C:\mingw\msys\1.0\bin`
- For MinGW32, navigate to the project root and execute `make MINGW32=1`. The process will take longer than Visual Studio.
- For MinGW64, refer to the respective documentation: [Linux](Support/INSTALL_linux.md) | [Windows](Support/INSTALL_windows.md) | [Mac](Support/INSTALL_mac.md). Note that only x86 systems may be targeted for the time being.
### Building with MinGW
- Execute `make MINGW32=1` for **MinGW32** or `make` for **MinGW64**. Optionally add `debug` to build with debug features.
Compiling Definitions
- `COPYPROT` (default: on) will define whether or not to use the CD drive for DIABDAT.MPQ
- `DEBUGGER` (default: off) will define whether to skip reloading for direct execution through debuggers
- `SLEEP` (default: off) will define whether to sleep the program to prevent 100% CPU usage
- `_DEBUG` (default: off) will define whether to include debug features (refer to [Debugging Document](Support/debug.md))
To compile with MinGW64 on different platforms, refer to the respective documentation: [Linux](Support/INSTALL_linux.md) | [Windows](Support/INSTALL_windows.md) | [Mac](Support/INSTALL_mac.md).
# [Compatibility Matrix, Compilations, Platform Statuses](Support/compatibility_matrix.md)
[Debug Build Features](Support/debug.md)
| [Compatibility Matrix](Support/compatibility_matrix.md)
| [Troubleshooting](Support/troubleshooting.md)
# Installing
Once compiled, the Devilution binary will serve as a replacement for `Diablo.exe`. A clean installation of Diablo patched to 1.09(b) is needed to run the game. Either copy Devilution into Diablo's installation folder, or make sure the following files are present:
- `DIABDAT.MPQ` : if `COPYPROT` was defined, then the Diablo CD will be required
- `DiabloUI.dll` : provides module for the title screen interface
- `SmackW32.dll` : provides library for playing Smacker video files
- `Standard.snp` : provides local multiplayer code (Modem/IPX/Serial, Starcraft version adds TCP/IP)
- `Storm.dll` : provides various "standard" functions
Once compiled, the Devilution binary will serve as a replacement for `Diablo.exe`. The following files from the original game patched to 1.09(b) need to be present: `DIABDAT.MPQ`, `DiabloUI.dll`, `SmackW32.dll`, `Standard.snp`, and `Storm.dll`. If `COPYPROT` was defined when compiling, the Diablo CD will also be required.
Additionally, Strange Bytes' [DirectDraw patch](http://www.strangebytes.com/index.php/projects/1-diablo-1-windows-7-vista-patch) is recommended to help fix compatibility issues and run the game in windowed mode.
To run the game in windowed mode, a DirectDraw wrapper will be needed. Strange Bytes' [DirectDraw patch](http://www.strangebytes.com/index.php/projects/1-diablo-1-windows-7-vista-patch) is recommended. To install, place the `ddraw.dll` into the same location as the Devilution binary.
# Multiplayer
TODO
# [Troubleshooting](Support/troubleshooting.md)
# Contributing
[Guidelines](Support/CONTRIBUTING.md)
# Modding
Here are some screenshots of a few things I tinkered around with, to demonstrate the relative ease of improving the game:
![Screenshot 1: Monster lifebar+items](https://s33.postimg.cc/6xnnhhlmn/diabuimon.png "Monster lifebar+items")
![Screenshot 2: New trade screen](https://s22.postimg.cc/z8fhuutk1/diabstore.png "New trade screen")
# F.A.Q.
> Wow, does this mean I can download and play Diablo for free now?
@ -89,49 +85,31 @@ Yes! However, this will be a **_side project_** based on Devilution. I have yet
Honestly I have no idea. More than 1,200 hours went into creating Devilution, and I have other things going on right now. Maybe in 6-12 months? The goal is to create a native Linux port, convert to OpenGL, modernize the UI, etc. you get the drill. There has to be some surprises. ;)
> Ok, so I'm playing Devilution now and all the sudden it crashed. NOW WHAT??
Try to remember as many details about the crash as possible. Inside the Diablo folder should be a log file containing crash information. Open an issue, upload the log, and provide as much information as possible (OS version, etc.).
Open an issue and provide as much information as possible (OS version, etc.) including any crash logs.
> I thought I'd fix the crash myself, but after looking at the code its a disaster. Do you speak v2-34-v8?
That is the result of decompiled code. Whenever a program is compiled, much of the source is optimized and stripped away, so it's nearly impossible to decompile it back. Have patience. Everything will be cleaned up eventually. :)
> Will you be reverse engineering Diablo II next? Ooooh please!
Absolutely not. Diablo II is still supported, sold, and maintained by Blizzard. Setting the legal implications aside, there's about 8x as much code, and a chance Blizzard will remaster the game soon anyway. (as of 2018)
Absolutely not. Diablo II would require far more work and is still supported by Blizzard. Setting that aside, there are rumors that the game will be remastered which takes the point out of it.
> Are you interested in working for me? I have this game I want you to reverse...
Sorry, but no. Money takes the passion out of it. Forgoing that, Diablo was an exception given that symbolic information was readily available. Even then it took countless hours to pick apart such a tiny game.
Sorry, but no. This project is time consuming enough as it is, and it's just a hobby.
> I think that's about all, but is Devilution even legal?
That's a tricky question. Under the DMCA, reverse-engineering has exceptions for the purpose of documentation and interoperability. Devilution provides the necessary documentation needed to achieve the latter. However, it falls into an entirely grey area. The real question is whether or not Blizzard deems it necessary to take action.
# Contributing
Currently there are a few issues with the decompiled code. The focus should be on fixing these issues for now instead of cleaning up the code. Currently only Diablo.exe has been reversed, the other files are:
- `Battle.snp`: code for battle.net, outdated protocol and not worth the time.
- `DiabloUI.dll`: code for the main menu, this is entirely Windows specific and poorly written. However, it needs to be reversed to complete the source code.
- `SmackW32.dll`: code for the Smacker video library, not worth the time.
- `Standard.snp`: code for local multiplayer, again outdated. Starcraft uses the same format and TCP/IP was added in a later patch. Reversing the UDP portion is desired.
- `Storm.dll`: we want Diablo to be independent of this library, the main file functions have been reversed as part of StormLib.
- `VidSize.exe`: changes one byte in registry, ignore.
If you are experienced with reversing, help is needed to reverse the user interface (DiabloUI) to help make Diablo cross-platform.
# Modding
Here are some screenshots of a few things I tinkered around with, to demonstrate the relative ease of improving the game:
![Screenshot 1: Monster lifebar+items](https://s33.postimg.cc/6xnnhhlmn/diabuimon.png "Monster lifebar+items")
![Screenshot 2: New trade screen](https://s22.postimg.cc/z8fhuutk1/diabstore.png "New trade screen")
# Credits
- [sanctuary](https://github.com/sanctuary) - documenting the Windows-specific Diablo code (engine, mpq, directx)
- [sanctuary](https://github.com/sanctuary) - extensively documenting Diablo's game engine
- [BWAPI Team](https://github.com/bwapi) - providing library API to work with Storm
- [Ladislav Zezula](https://github.com/ladislav-zezula) - decompiling PKWARE library, decompiling Storm (StormLib)
- [Ladislav Zezula](https://github.com/ladislav-zezula) - reversing PKWARE library, further documenting Storm
- [fearedbliss](https://github.com/fearedbliss) - being awe-inspiring
- Climax Studios & Sony - secretly helping with their undercover QA :P
- Blizzard North - wait, this was a typo!
- Depression - reason to waste four months of my life doing this ;)
# Legal
This work is being released to the Public Domain. No assets of Diablo are being provided. You must own a copy of Diablo and have access to the assets beforehand in order to use this software.
This software is being released to the Public Domain. No assets of Diablo are being provided. You must own a copy of Diablo and have access to the assets beforehand in order to use this software.
Battle.net(R) - Copyright (C) 1996 Blizzard Entertainment, Inc. All rights reserved. Battle.net and Blizzard Entertainment are trademarks or registered trademarks of Blizzard Entertainment, Inc. in the U.S. and/or other countries.

184
Source/engine.cpp

@ -181,11 +181,12 @@ void __fastcall CelDecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_c
char *v6; // ebx
int v7; // edx
int v8; // eax
int v9; // [esp+0h] [ebp-1Ch]
char *v10; // [esp+4h] [ebp-18h]
int v9; // ST00_4
char *a3; // [esp+Ch] [ebp-10h]
if ( pDecodeTo && pRLEBytes )
{
a3 = &pLightTbl[256 * light_table_index];
v4 = pRLEBytes;
v5 = pDecodeTo;
v6 = &pRLEBytes[frame_content_size];
@ -197,15 +198,15 @@ void __fastcall CelDecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_c
while ( 1 )
{
v8 = (unsigned char)*v4++;
if ( (v8 & 0x80u) != 0 )
if ( (v8 & 0x80u) != 0 ) /* check sign */
break;
CelDecDatLightEntry(v8, (char *)(v7 - v8), (char *)(v7 - v8), v6);
v9 = v7 - v8;
CelDecDatLightEntry(v8, a3, v5, v4);
v7 = v9;
v6 = v10;
if ( !v9 )
goto LABEL_9;
}
v8 = -(char)v8;
_LOBYTE(v8) = -(char)v8;
v5 += v8;
v7 -= v8;
}
@ -218,55 +219,55 @@ LABEL_9:
}
// 69BEF8: using guessed type int light_table_index;
void __fastcall CelDecDatLightEntry(int a1, char *a2, char *a3, char *v6)
void __fastcall CelDecDatLightEntry(unsigned char shift, char *LightIndex, char *&pDecodeTo, char *&pRLEBytes)
{
int v4; // ebx
// _BYTE *v6; // esi
char v7; // cf
unsigned char v8; // cl
char v9; // cl
int v10; // eax
char v5; // cf
unsigned char v6; // cl
char v7; // cl
int v8; // eax
char v9; // ch
int tmp; // eax
char v11; // ch
char v12; // ch
char v13; // ch
char a1;
v7 = a1 & 1;
v8 = (unsigned char)a1 >> 1;
if ( v7 )
v5 = shift & 1;
v6 = shift >> 1;
if ( v5 )
{
*a2 = *v6;
*a3 = a2[v4];
++v6;
++a3;
a1 = *pRLEBytes;
*pDecodeTo = LightIndex[a1];
++pRLEBytes;
++pDecodeTo;
}
v7 = v8 & 1;
v9 = v8 >> 1;
if ( v7 )
v5 = v6 & 1;
v7 = v6 >> 1;
if ( v5 )
{
*a2 = *v6;
*a3 = a2[v4];
*a2 = v6[1];
a3[1] = a2[v4];
v6 += 2;
a3 += 2;
a1 = *pRLEBytes;
*pDecodeTo = LightIndex[a1];
a1 = pRLEBytes[1];
pDecodeTo[1] = LightIndex[a1];
pRLEBytes += 2;
pDecodeTo += 2;
}
for ( ; v9; --v9 )
for ( ; v7; --v7 )
{
v10 = *(_DWORD *)v6;
v6 += 4;
*a2 = v10;
v11 = a2[v4];
*a2 = BYTE1(v10);
v10 = __ROR4__(v10, 16);
*a3 = v11;
v12 = a2[v4];
*a2 = v10;
a3[1] = v12;
v13 = a2[v4];
*a2 = BYTE1(v10);
a3[2] = v13;
a3[3] = a2[v4];
a3 += 4;
v8 = *(_DWORD *)pRLEBytes;
pRLEBytes += 4;
a1 = v8;
v9 = LightIndex[a1];
a1 = BYTE1(v8);
tmp = __ROR4__(v8, 16);
*pDecodeTo = v9;
v11 = LightIndex[a1];
a1 = tmp;
pDecodeTo[1] = v11;
v12 = LightIndex[a1];
a1 = BYTE1(tmp);
pDecodeTo[2] = v12;
pDecodeTo[3] = LightIndex[a1];
pDecodeTo += 4;
}
}
@ -430,9 +431,9 @@ void __fastcall CelDecodeLightOnly(int screen_x, int screen_y, char *pCelBuff, i
v7 = &pCelBuff[v6];
v8 = (char *)gpBuffer + screen_y_times_768[v5] + screen_x;
v9 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v6;
/*if ( light_table_index )
if ( light_table_index )
CelDecDatLightOnly(v8, v7, v9, frame_width);
else */
else
CelDrawDatOnly(v8, v7, v9, frame_width);
}
}
@ -470,9 +471,9 @@ void __fastcall CelDecodeHdrLightOnly(int screen_x, int screen_y, char *pCelBuff
v12 = *(_DWORD *)&v8[4 * frame + 4] - v9 - (_DWORD)cel_buf;
v13 = &v10[(_DWORD)cel_buf];
v14 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * always_0] + v15;
/*if ( light_table_index )
if ( light_table_index )
CelDecDatLightOnly(v14, v13, v12, frame_width);
else*/
else
CelDrawDatOnly(v14, v13, v12, frame_width);
}
}
@ -510,10 +511,10 @@ void __fastcall CelDecodeHdrLightTrans(char *pBuff, char *pCelBuff, int frame, i
{
CelDecDatLightTrans(pBuff, v12, v11, frame_width);
}
/*else if ( light_table_index )
else if ( light_table_index )
{
CelDecDatLightOnly(pBuff, v12, v11, frame_width);
}*/
}
else
{
CelDrawDatOnly(pBuff, v12, v11, frame_width);
@ -757,9 +758,11 @@ void __fastcall Cel2DecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_
int v7; // edx
int v8; // eax
int v9; // ST00_4
char *a3; // [esp+Ch] [ebp-10h]
if ( pDecodeTo && pRLEBytes && gpBuffer )
{
a3 = &pLightTbl[256 * light_table_index];
v4 = pRLEBytes;
v5 = pDecodeTo;
v6 = &pRLEBytes[frame_content_size];
@ -770,8 +773,8 @@ void __fastcall Cel2DecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_
{
while ( 1 )
{
v8 = (unsigned char)*v4++;
if ( (v8 & 0x80u) == 0 )
v8 = (unsigned __int8)*v4++;
if ( (v8 & 0x80u) == 0 ) /* check sign */
break;
_LOBYTE(v8) = -(char)v8;
v5 += v8;
@ -783,7 +786,7 @@ void __fastcall Cel2DecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_
if ( (unsigned int)v5 < screen_buf_end )
{
v9 = v7;
Cel2DecDatLightEntry(v8, v7);
Cel2DecDatLightEntry(v8, a3, v5, v4);
v7 = v9;
}
else
@ -802,56 +805,55 @@ LABEL_13:
// 69BEF8: using guessed type int light_table_index;
// 69CF0C: using guessed type int screen_buf_end;
void __fastcall Cel2DecDatLightEntry(int a1, int a2)
void __fastcall Cel2DecDatLightEntry(unsigned char shift, char *LightIndex, char *&pDecodeTo, char *&pRLEBytes)
{
int v2; // ebx
_BYTE *v3; // edi
_BYTE *v4; // esi
char v5; // cf
unsigned char v6; // cl
char v7; // cl
int v8; // eax
char v9; // ch
char v10; // ch
int tmp; // eax
char v11; // ch
char v12; // ch
char a1;
v5 = a1 & 1;
v6 = (unsigned char)a1 >> 1;
v5 = shift & 1;
v6 = shift >> 1;
if ( v5 )
{
_LOBYTE(a2) = *v4;
*v3 = *(_BYTE *)(v2 + a2);
++v4;
++v3;
a1 = *pRLEBytes;
*pDecodeTo = LightIndex[a1];
++pRLEBytes;
++pDecodeTo;
}
v5 = v6 & 1;
v7 = v6 >> 1;
if ( v5 )
{
_LOBYTE(a2) = *v4;
*v3 = *(_BYTE *)(v2 + a2);
_LOBYTE(a2) = v4[1];
v3[1] = *(_BYTE *)(v2 + a2);
v4 += 2;
v3 += 2;
a1 = *pRLEBytes;
*pDecodeTo = LightIndex[a1];
a1 = pRLEBytes[1];
pDecodeTo[1] = LightIndex[a1];
pRLEBytes += 2;
pDecodeTo += 2;
}
for ( ; v7; --v7 )
{
v8 = *(_DWORD *)v4;
v4 += 4;
_LOBYTE(a2) = v8;
v9 = *(_BYTE *)(v2 + a2);
_LOBYTE(a2) = BYTE1(v8);
v8 = __ROR4__(v8, 16);
*v3 = v9;
v10 = *(_BYTE *)(v2 + a2);
_LOBYTE(a2) = v8;
v3[1] = v10;
v11 = *(_BYTE *)(v2 + a2);
_LOBYTE(a2) = BYTE1(v8);
v3[2] = v11;
v3[3] = *(_BYTE *)(v2 + a2);
v3 += 4;
v8 = *(_DWORD *)pRLEBytes;
pRLEBytes += 4;
a1 = v8;
v9 = LightIndex[a1];
a1 = BYTE1(v8);
tmp = __ROR4__(v8, 16);
*pDecodeTo = v9;
v11 = LightIndex[a1];
a1 = tmp;
pDecodeTo[1] = v11;
v12 = LightIndex[a1];
a1 = BYTE1(tmp);
pDecodeTo[2] = v12;
pDecodeTo[3] = LightIndex[a1];
pDecodeTo += 4;
}
}
@ -1045,9 +1047,9 @@ void __fastcall Cel2DecodeHdrLight(int screen_x, int screen_y, char *pCelBuff, i
v14 = v12 - (_DWORD)cel_buf;
v15 = &v10[(_DWORD)cel_buf];
v16 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + screen_x;
/*if ( light_table_index )
if ( light_table_index )
Cel2DecDatLightOnly(v16, v15, v14, frame_width);
else*/
else
Cel2DecDatOnly(v16, v15, v14, frame_width);
}
}
@ -1087,10 +1089,10 @@ void __fastcall Cel2DecodeLightTrans(char *dst_buf, char *pCelBuff, int frame, i
{
Cel2DecDatLightTrans(dst_buf, v13, v12, frame_width);
}
/*else if ( light_table_index )
else if ( light_table_index )
{
Cel2DecDatLightOnly(dst_buf, v13, v12, frame_width);
}*/
}
else
{
Cel2DecDatOnly(dst_buf, v13, v12, frame_width);

4
Source/engine.h

@ -21,7 +21,7 @@ void __fastcall CelDecDatOnly(char *pBuff, char *pCelBuff, int frame, int frame_
void __fastcall CelDrawHdrOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction);
void __fastcall CelDecodeHdrOnly(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction);
void __fastcall CelDecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width);
void __fastcall CelDecDatLightEntry(int a1, char *a2, char *a3, char *v6);
void __fastcall CelDecDatLightEntry(unsigned char shift, char *LightIndex, char *&pDecodeTo, char *&pRLEBytes); /* __usercall a1@<cl> a2@<ebx> a3@<edi> a4@<esi> */
void __fastcall CelDecDatLightTrans(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width);
void __fastcall CelDecodeLightOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width);
void __fastcall CelDecodeHdrLightOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction);
@ -31,7 +31,7 @@ void __fastcall Cel2DecDatOnly(char *pDecodeTo, char *pRLEBytes, int frame_conte
void __fastcall Cel2DrawHdrOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction);
void __fastcall Cel2DecodeHdrOnly(char *pBuff, char *pCelBuff, int frame, int frame_width, int a5, int direction);
void __fastcall Cel2DecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width);
void __fastcall Cel2DecDatLightEntry(int a1, int a2);
void __fastcall Cel2DecDatLightEntry(unsigned char shift, char *LightIndex, char *&pDecodeTo, char *&pRLEBytes); /* __usercall a1@<cl> a2@<ebx> a3@<edi> a4@<esi> */
void __fastcall Cel2DecDatLightTrans(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width);
void __fastcall Cel2DecodeHdrLight(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction);
void __fastcall Cel2DecodeLightTrans(char *dst_buf, char *pCelBuff, int frame, int frame_width, int a5, int direction);

0
CONTRIBUTING.md → Support/CONTRIBUTING.md

25
Support/TODO.md

@ -0,0 +1,25 @@
### Comments
- `BUG_FIX` known bugs in original (vanilla) code
- `/* */` block comments are things to be fixed/checked
- `FIX_ME` bad data
### Known Bugs
Serious bugs (crash/fault)
- TBA
Minor bugs (noticeable but can be avoided)
- Generation of Cathedral/Catacombs walls and floors are slightly inaccurate
- Some spells don't use any mana or charges when they should
- Some tiles are drawn fully lit when they should be transparent `world.cpp`
- Timed messages are broken and have been disabled `tmsg.cpp`
- Server commands are broken and have been disabled `msgcmd.cpp`
- Automap drawing is slightly incorrect
Code issues (incorrect code that still works)
- Critical sections should be constructors using `CCritSect`
- Function `DRLG_L4TransFix`, decompile and check (Test: seed `2349839` level 13)
- Some code uses macros such as `__PAIR__` or `__ROL4__`, or `__int64`
- Some functions/structures have incorrect signing (signed/unsigned BYTE)
- Function `GetLevelMTypes`, decompile and check `monster.cpp`
- Function `SetAutomapView`, decompile and check `automap.cpp`
- Function `engine_draw_automap_pixels`, decompile and check `engine.cpp`

25
TODO

@ -1,25 +0,0 @@
[COMMENTS IN CODE]
BUG_FIX known bugs in original code (to be kept that way, but with fix in comments)
/* block comments are things to be fixed/checked
FIX_ME bad data
[PROBLEMS IN DECOMPILED CODE]
1xxx Serious bugs (crash/fault)
2xxx Minor bugs (noticeable but can be avoided)
3xxx Code issues (incorrect code that still compiles/works)
2000 - Generation of Cathedral/Catacombs is slightly inaccurate
2001 - Some spells don't use any mana or charges when they should
2002 - Some tiles are drawn fully lit when they should be transparent (world.cpp)
2003 - Objects should darken with radius instead of being fully lit
2004 - Some CEL functions were written in ASM and have been disabled (engine.cpp)
2005 - Timed messages are broken and have been disabled (tmsg.cpp)
2006 - Server commands are broken and have been disabled (msgcmd.cpp)
3000 - Critical sections should be constructors using CCritSect
3001 - Function 'DRLG_L4TransFix', decompile and check (Test: seed 2349839 level 13)
3002 - Some code uses macros such as __PAIR__ or __ROL4__, or __int64
3003 - Some functions/structures have incorrect signing (signed/unsigned BYTE)
3004 - Function 'GetLevelMTypes', decompile and check (monster.cpp)
3005 - Function 'SetAutomapView', decompile and check (automap.cpp)
3006 - Function 'engine_draw_automap_pixels', decompile and check (engine.cpp)
Loading…
Cancel
Save