-
Notifications
You must be signed in to change notification settings - Fork 920
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
Conversation
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); |
There was a problem hiding this comment.
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);
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this 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 :)
mainmenu_loop(); | ||
UiDestroy(); | ||
SaveGamma(); | ||
if (ghMainWnd) { | ||
|
||
if(ghMainWnd) { |
There was a problem hiding this comment.
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))) |
There was a problem hiding this comment.
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.
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.