Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WinMain+Direct file access from HDD #456

Merged
3 commits merged into from Nov 9, 2018
Merged

WinMain+Direct file access from HDD #456

3 commits merged into from Nov 9, 2018

Conversation

ghost
Copy link

@ghost ghost commented Nov 8, 2018

WinMain is now bin exact.

New feature ported from the 1.00: as part of the no-cd regime, loading MPQs locally, there was another feature that was missing to enable direct file access. Anyone who mods Diablo 2 will be familiar with the -direct command. This is the D1 equivalent. The debug build will scan directly for the files first, and if not found THEN the mpq.

@AJenbo
Copy link
Member

AJenbo commented Nov 8, 2018

holy grail

Source/diablo.h Outdated
bool __cdecl diablo_get_not_running();
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
BOOL __cdecl diablo_get_not_running();
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've never seen the PASCAL calling convention being used in a C/C++ project before. Most often, WINAPI is used for the WinMain function.

Would WinMain still be bin exact with the following signature?

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't 100% sure what to use here, since PASCAL/WINAPI/APIENTRY/CALLBACK are all __stdcalls. Given that the demo version is a direct copy/paste of the WinMain routine from the DX2 SDK, this signature is exactly the same as what was in the SDK. So it should be correct, though I'd use APIENTRY for my code.

Copy link
Contributor

@mewmew mewmew Nov 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, makes sense. Still boggles my mind to have a PASCAL calling convention though, as the arguments are passed in reverse order as opposed to regular C calling conventions?

From https://en.wikipedia.org/wiki/X86_calling_conventions#pascal:

  • pascal: parameters are pushed on the stack in left-to-right order (opposite of cdecl)
  • stdcall: parameters are pushed onto the stack in right-to-left order

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a bit of research it seems that pascal with near/far was common in 16-bit programs. When 32-bit was introduced it became obsolete. During the 16->32 transition, it was often necessary to keep compatibility with both, so DOS and Windows 95 could be targeted (similar to how most programs still have 32 and 64 versions to this day). Compilers adapted so that PASCAL evaluates to __stdcall for 32-bit, but continued to use traditional pascal for 16-bit. See here:
https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-tools/widl/include/windef.h#L165
To further complicate the issue, Diablo was written during the tail-end of the 16-bit era. I recall the 1994 or so pitch was that it would be a turn based-DOS game. They started development before both Windows 95 and DirectX 1.0 came out, and the first screenshots appeared around the time they did.

I don't think it should be an issue though, PASCAL and WINAPI generate the same code. It was likely also used for the WindowProc routine, i.e.:
LONG FAR PASCAL WindowProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll probably change it back, just to prevent confusion.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, I'd prefer if when converting a function from one call type to another, We could use an alias instead if just changing the call type, for the sake of documentation and future reference.

for example, instead of doing

__original_calltype --> __stdcall

I'd prefer

#define ORIGINAL_CALLTYPE __stdcall

:D

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I seam to remember having heard that they originally wanted to target dos.

Copy link
Member

@AJenbo AJenbo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct file access is going to make modding much easier, thanks for doing this so others don't have to :)

Source/diablo.cpp Show resolved Hide resolved
mainmenu_loop();
UiDestroy();
SaveGamma();
if (ghMainWnd) {

if(ghMainWnd) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (ghMainWnd != NULL) {

*Filename = '\0';
DirErrorDlg(Filename);
if(ReadOnlyTest()) {
if(!GetModuleFileName(ghInst, szFileName, sizeof(szFileName)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (GetModuleFileName(...) == 0)

GetModuleFileName returns the length of the returned name, not a boolean value.

Source/diablo.cpp Show resolved Hide resolved
@ghost ghost merged commit 24285a2 into diasurgical:nightly Nov 9, 2018
@ghost ghost deleted the WinMain branch November 9, 2018 22:23
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants