As I've promised earlier - I've updated the first post with a new build.
As I've promised earlier - I've updated the first post with a new build.
Glad to hear this has finally reached beta, but every time I try to run anything other than the H3 Demo file provided in previous versions, I get the "Error in the emulated program" message. Including HOMM3 Complete with the 32-bit patch or the HD patch set to 32-bit. I enabled full logging in the registry, and the file literally says "Logger initialised" and "Logger unloaded"
"Error in the emulated program" means that there is a problem with a program you are trying to execute and emulator can't even start running it.
Here are the reasons: emulated EXE cannot be found or somehow is inaccessible (for example due to NTFS permissions), there is error in the file format (not x86 PE), loader can't find peldr.nt.dll (broken installation), or loader can't reserve memory. In the last case the peloader.exe would be relaunched 100 times and you'll see that it writes the line "Failed to reserve memory (0x%08x, %d) due to ASLR, please rerun the application". Normally it needs 1-3 peloader.exe restarts depending on the size of a program.
I've attached an updated launcher.exe that provides exact reason of the error. Replace the old one and try again.
One more note. If you don't specify log file name in registry - the log would be created in %temp% and there would be 2 log files. One for launcher and the second for the actual emulator.
edited: attached the file to the first post. Also fixed the no sound problem in pinball and some other programs.
Though _HD3_.dll does exist.[2682B875]E: PeLdr can't open file: PSAPI.DLL
[2682B875]E: Import dll PSAPI.DLL not found
[2682B875]E: Import dll _HD3_.dll not found
You are right - spaces and quotes in the EXE file name are not supported - I'll fix that.Edit2: Could it be spaces in the location of the exe? Going to test in a moment...
This means that _HD3_.dll can't be loaded due to PSAPI.DLL not found. There is a mistake in the error message, it should be "import dll xxx or some of its dependencies not found".[2682B875]E: PeLdr can't open file: PSAPI.DLL
[2682B875]E: Import dll PSAPI.DLL not found
[2682B875]E: Import dll _HD3_.dll not found
... Though _HD3_.dll does exist.
Strange, after I installed this program, my tablet became very buggy: ... even after reboot(without launching jailbreak, even). I realize, that its very improbable that it is your app...
XnView: MSVFW32.dll not found.[001E926A]E: Import ordinal 74 not found in C:\Program Files\win86emu\System32\SHELL32.86.dll
[001E926A]E: Import ordinal 680 not found in C:\Program Files\win86emu\System32\SHELL32.86.dll
xnview, mplayer and foobar2000 are on the list just because there's no decent alternative to them, I still couldn't find the store app that handles .gif files well, for example. Also, tried launching leaked beta build of half-life, but it requires opengl which is, as I've read in other thread, is very improbable to run well enough.
Disabling ShowIntro (in the registry, under the emulated HKLM) let me get past that. Alternatively, run the un-color-patched version; it looks awful and runs slowly, but once you sit through the into once you can skip it in future bit hitting Esc during the "3DO" video.
Not exactly a port, it is a clean remake based on the old ideas.heh, is this a port of the app you showed off back in the CE days? -awesome getting that ported over
The idea is very simple:
#define DEFINE_FUNC1(name) \
static const ModuleDef str_##name={DLL_NAME,#name}; \
EXTERN_C DW STUB_EXPORT stub_##name(DW p1) \
{ \
DW *p=&p1; \
__asm { mov eax,p } \
__asm { jmp f1 } \
__asm { mov eax,offset str_##name } \
f1: __asm { in eax,0xe5 } \
__asm { mov p,eax } \
return (DW)p; \
}
.....
#define DEFINE_FUNC3(name) \
static const ModuleDef str_##name={DLL_NAME,#name}; \
EXTERN_C DW STUB_EXPORT stub_##name(DW p1,DW p2,DW p3) \
{ \
DW *p=&p1; \
__asm { mov eax,p } \
__asm { jmp f1 } \
__asm { mov eax,offset str_##name } \
f1: __asm { in eax,0xe5 } \
__asm { mov p,eax } \
return (DW)p; \
}
....
DEFINE_FUNC1(AddAtomA)
DEFINE_FUNC1(AddAtomW)
DEFINE_FUNC7(CreateFileA) -- number in macro == number of parameters to a __stdcall WinAPI function.
Compiler automatically generates "ret N*4" at the end of such function.
I've decided to use such c+asm approach instead of making a tiny assebler stub,
as I can easily implement some of such functions in C directly in a stub DLL plus it
simplifies debugging. And the functions have a usual C prologue/epilogue, so that
the emulated program may even patch them in runtime, for example for hooks.
...
#define DEFINE_FUNC1(name) \
EXTERN_C DW STUB_IMPORT name(DW); \ -- this behaves like a function prototype to compiler
EXTERN_C DW STUB_EXPORT yact_##name(DW *R) \ -- R - pointer to the x86 stack
{ \
DW r=name(p1); \ // call the func passing it paramers from the emulated stack, p1==R[0], p2==R[1] and so on
LEAVE(1); \ // empty macro, as the stack is unwinded in x86 stub DLL now
return r; \
}
...
#define DEFINE_FUNC3(name) \
EXTERN_C DW STUB_IMPORT name(DW,DW,DW); \
EXTERN_C DW STUB_EXPORT yact_##name(DW *R) \
{ \
DW r=name(p1,p2,p3); \
LEAVE(3); \
return r; \
}
...
DEFINE_FUNC1(AddAtomA)
DEFINE_FUNC1(AddAtomW)
DEFINE_FUNC7(CreateFileA) // as you see - implementation part is identical to an x86 stub, so I can use the same stub-generator tool
static DWORD WINAPI ThreadProc(
LPVOID lpParameter // [0] == orig func, [1] == orig param
)
{
__EXCEPTION_REGISTRATION_RECORD R;
DWORD *Parm=(DWORD*)lpParameter;
DWORD *TEB=(DWORD*)PeLdrGetCurrentTeb();
R.Next=(__EXCEPTION_REGISTRATION_RECORD*)-1;
R.Handler=(void*)CbReturnToHost();
TEB[0]=(DWORD)&R; // in case of unhandled exception - just return
PeLdrNotifyNewThread(NULL,DLL_THREAD_ATTACH);
DWORD Ret=EmuExecute(Parm[0],1,Parm[1]); // 1 == number of parameters to the emulated function
delete Parm;
return Ret;
}
EXTERN_C DW STUB_EXPORT yact_CreateThread(DW *R)
{
DWORD* Parm=new DWORD[2];
Parm[0]=p3; // TODO: no out-of-memory checking for now
Parm[1]=p4;
DWORD StackSize=p2;
if(StackSize)
StackSize+=1024*1024; // I reserve some space for my own needs (debugging)
else
StackSize=2*1024*1024; // TODO: I don't support autogrow stacks, so reserve 2 Mb
DWORD t=(DWORD)CreateThread((LPSECURITY_ATTRIBUTES)p1,StackSize,ThreadProc,Parm,p5,(LPDWORD)p6);
LEAVE(6);
return t;
}