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
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 3rdParty/Storm/Source/storm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,4 @@ BOOL __stdcall SDlgKillTimer(int a1, int a2) rBool;
BOOL __stdcall SDlgDrawBitmap(HWND hWnd, int a2, int a3, int a4, int a5, int a6, int a7) rBool;
BOOL __stdcall SDlgDialogBoxParam(HINSTANCE hInst, char *szDialog, int a3, WNDPROC func, int a5) rBool;
BOOL __stdcall SGdiTextOut(void *pBuffer, int x, int y, int mask, char *str, int len) rBool;
BOOL __stdcall SFileEnableDirectAccess(BOOL enable) rBool;
2 changes: 1 addition & 1 deletion 3rdParty/Storm/Source/storm.def
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ EXPORTS
SFileDdaInitialize @260 NONAME
SFileDdaSetVolume @261 NONAME
SFileDestroy @262 NONAME
;SFileEnableDirectAccess @263 NONAME
SFileEnableDirectAccess @263 NONAME
SFileGetFileArchive @264 NONAME
SFileGetFileSize @265 NONAME
SFileOpenArchive @266 NONAME
Expand Down
1 change: 1 addition & 0 deletions 3rdParty/Storm/Source/storm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,7 @@ BOOL __stdcall SDlgKillTimer(int a1, int a2);
BOOL __stdcall SDlgDrawBitmap(HWND hWnd, int a2, int a3, int a4, int a5, int a6, int a7);
BOOL __stdcall SDlgDialogBoxParam(HINSTANCE hInst, char *szDialog, int a3, WNDPROC func, int a5);
BOOL __stdcall SGdiTextOut(void *pBuffer, int x, int y, int mask, char *str, int len);
BOOL __stdcall SFileEnableDirectAccess(BOOL enable);

#ifdef __GNUC__
}
Expand Down
3 changes: 2 additions & 1 deletion 3rdParty/Storm/Source/storm_gcc.def
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ EXPORTS
SFileDdaSetVolume @261 NONAME
SFileDdaSetVolume@12 @261 NONAME
SFileDestroy @262 NONAME
;SFileEnableDirectAccess @263 NONAME
SFileEnableDirectAccess @263 NONAME
SFileEnableDirectAccess@4 @263 NONAME
SFileGetFileArchive @264 NONAME
SFileGetFileArchive@8 @264 NONAME
SFileGetFileSize @265 NONAME
Expand Down
68 changes: 39 additions & 29 deletions Source/diablo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,71 +254,81 @@ void __cdecl free_game()
FreeGameMem();
}

bool __cdecl diablo_get_not_running()
BOOL __cdecl diablo_get_not_running()
{
SetLastError(0);
CreateEvent(NULL, FALSE, FALSE, "DiabloEvent");
return GetLastError() != ERROR_ALREADY_EXISTS;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HINSTANCE v4; // esi
char Filename[260]; // [esp+8h] [ebp-10Ch]
char value_name[8]; // [esp+10Ch] [ebp-8h]
HINSTANCE hInst;
int nData;
char szFileName[MAX_PATH];

v4 = hInstance;
hInst = hInstance;
#ifndef DEBUGGER
diablo_reload_process(hInstance);
#endif
ghInst = v4;
if (RestrictedTest())
ghInst = hInst;

if(RestrictedTest())
ErrOkDlg(IDD_DIALOG10, 0, "C:\\Src\\Diablo\\Source\\DIABLO.CPP", 877);
if (ReadOnlyTest()) {
if (!GetModuleFileName(ghInst, Filename, 0x104u))
*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.

szFileName[0] = '\0';
DirErrorDlg(szFileName);
}

ShowCursor(FALSE);
srand(GetTickCount());
InitHash();
exception_get_filter();
if (!diablo_find_window("DIABLO") && diablo_get_not_running()) {

BOOL bNoEvent = diablo_get_not_running();
if(!diablo_find_window("DIABLO") && bNoEvent) {
#ifdef _DEBUG
SFileEnableDirectAccess(TRUE);
#endif
diablo_init_screen();
diablo_parse_flags(lpCmdLine);
init_create_window(nCmdShow);
sound_init();
UiInitialize();

#ifdef _DEBUG
if (showintrodebug)
play_movie("gendata\\logo.smk", 1);
#else
play_movie("gendata\\logo.smk", 1);
if(showintrodebug)
#endif
strcpy(value_name, "Intro");
if (!SRegLoadValue("Diablo", value_name, 0, (int *)&hInstance))
hInstance = (HINSTANCE)1;
if (hInstance)
play_movie("gendata\\diablo1.smk", 1);
SRegSaveValue("Diablo", value_name, 0, 0);
play_movie("gendata\\logo.smk", TRUE);
AJenbo marked this conversation as resolved.
Show resolved Hide resolved

char szValueName[] = "Intro";
if(!SRegLoadValue("Diablo", szValueName, 0, &nData))
nData = 1;
if(nData)
AJenbo marked this conversation as resolved.
Show resolved Hide resolved
play_movie("gendata\\diablo1.smk", TRUE);
SRegSaveValue("Diablo", szValueName, 0, 0);

#ifdef _DEBUG
if (showintrodebug) {
if(showintrodebug) {
#endif
UiTitleDialog(7);
BlackPalette();
#ifdef _DEBUG
}
#else
UiTitleDialog(7);
BlackPalette();
#endif

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) {

Sleep(300);
DestroyWindow(ghMainWnd);
}
}
return 0;

return FALSE;
}

void __fastcall diablo_parse_flags(char *args)
Expand Down
4 changes: 2 additions & 2 deletions Source/diablo.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ int __fastcall diablo_init_menu(int a1, int bSinglePlayer);
void __fastcall run_game_loop(int uMsg);
void __fastcall start_game(int uMsg);
void __cdecl free_game();
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.

void __fastcall diablo_parse_flags(char *args);
void __cdecl diablo_init_screen();
BOOL __fastcall diablo_find_window(LPCSTR lpClassName);
Expand Down
11 changes: 10 additions & 1 deletion Source/effects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1042,12 +1042,21 @@ void __fastcall PlaySFX_priv(TSFX *pSFX, BOOL loc, int x, int y)

void __fastcall stream_play(TSFX *pSFX, int lVolume, int lPan)
{
/// ASSERT: assert(pSFX);
/// ASSERT: assert(pSFX->bFlags & sfx_STREAM);
sfx_stop();
lVolume += sound_get_or_set_sound_volume(1);
if (lVolume >= VOLUME_MIN) {
if (lVolume > VOLUME_MAX)
lVolume = VOLUME_MAX;
if (!SFileOpenFile(pSFX->pszName, &sfx_stream)) {
#ifdef _DEBUG
SFileEnableDirectAccess(FALSE);
#endif
BOOL success = SFileOpenFile(pSFX->pszName, &sfx_stream);
#ifdef _DEBUG
SFileEnableDirectAccess(TRUE);
#endif
if (!success) {
sfx_stream = 0;
} else {
if (!SFileDdaBeginEx(sfx_stream, 0x40000, 0, 0, lVolume, lPan, 0))
Expand Down
7 changes: 7 additions & 0 deletions Source/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,16 @@ void __cdecl music_stop()

void __fastcall music_start(int nTrack)
{
/// ASSERT: assert((DWORD) nTrack < NUM_MUSIC);
music_stop();
if (sglpDS && gbMusicOn) {
#ifdef _DEBUG
SFileEnableDirectAccess(FALSE);
#endif
BOOL success = SFileOpenFile(sgszMusicTracks[nTrack], &sgpMusicTrack);
#ifdef _DEBUG
SFileEnableDirectAccess(TRUE);
#endif
sound_create_primary_buffer(sgpMusicTrack);
if (!success) {
sgpMusicTrack = 0;
Expand Down