Amiga.org
Operating System Specific Discussions => AROS Research Operating System => Topic started by: AmiDARK on June 08, 2014, 10:42:53 PM
-
Hello.
I tried to make a quick port of the AmiDARK Engine for AROS i386.
To show it should not be too complex.
Some functions don't work (like PTReplay musics, etc...)
Can someone with an i386 AROS, try this demo and tell me if it work correctly ?
If it work, can you post a screen capture of it ?
http://files.amidark-engine.com/FlyingFeather.zip
Thank you.
AmiDARK
-
I get a "not enough memory available" error, because you stripped the executable. If you do so, please always use the --strip-unneeded argument, otherwise the executable becomes unusable.
-
@BSZili : Ok.
Reuploaded without stripping.
Sad to see that stripping causes this problem (and I don't understand why) because executable is now 5Mb instead of 1Mb ...
Please test this new version (same link than previous)
-
I tried the demo, but it still doesn't work. It cannot open input.device, and I think I know why. On AROS, before you open input.device, you have to initialize the mn_Length field of the IORequest message, like this:
struct IOStdReq input_req;
(...)
input_req.io_Message.mn_Length = sizeof(input_req);
-
Thank you BSZili.
Will check this when I'll be back at home.
What you said here show that it is good to open source code as I don't have a computer with AROS, I can't test ...
Regards,
AmiDARK
-
I don't want to force anything on you, but if you have an x86 PC, then you have the computer to run AROS. You don't even have to install it, you can run it in VmWare, VirtualBox, QEMU, etc.
-
Uploaded a new version with your changes BSZili ;)
Same link.
-
It still crashes with the same error, and since the executable is stripped I can't get a backtrace. If you want you can download any AROS distro and run it in your VM of preference, so you can test the program yourself. If you don't want to download AROS, that's fin too, but I don't have the source code, so this is as far as I can go with guesswork.
-
BSZili, the executable is not stripped.
Strange that it crash with the same error.
I will investigate this.
Regards,
AmiDARK
-
Oops, my bad. I assumed you just added --strip-unneeded instead of removing the stripping altogether. This is the backtrace I get:
#0 0x885c80df in MyGetSysTime ()
#1 0x885c823e in deOpenDevice_Timer ()
#2 0x885b7023 in DarkENGINE_Start ()
#3 0x885b726e in main ()
-
I don't understand what your backtrace may learn us.
Because the AmiDARK Engine initialise this way :
int main( int myargc, char** myargv ){
BOOL eResult;
argc = myargc;
argv = myargv;
eResult = DarkENGINE_Start(); // <-- SETUPS
if ( eResult == TRUE ){
DarkLoop(); // <------------------ The main user/developer function
}
DarkENGINE_End(); // <------------ Releases/Clean up.
return EXIT_SUCCESS;
}
And the DarkENGINE_STart() function work this way :
BOOL mResult = TRUE;
DemoMode = 1;
deOpenLibraries();
deOpenDataTypes();
if( !deOpenDevice_Input() ){
mResult = FALSE;
printf( "Erreur opening Device Input\n" );
}
if( !deOpenDevice_Timer() ){
mResult = FALSE;
printf( "Erreur opening Device Timer\n" );
}
deOpenPTReplay();
// Setup de la liste de rendu graphique
AdvFunctionConstructor();
// Setup des plugins utilisés
...
...
...
return mResult;
}
Do you backtrace mean the last function called is the MyGetSysTime() one ?
Because deOpenDevice_Input() is called before deOpenDevice_Timer() that call the MyGetSysTime()...
I will burn a DVD with the latest AROS release .... But I'm not sure it help progress in the problem ...
-
You have to read the backtrace from the bottom to the top, the function which crashes the program is MyGetSysTime. If the debug symbols were present, the backtrace would have the exact file name and line numbers too.
You don't need to burn a DVD, just pop in an Icaros Desktop ISO into VMWare Player, and you have a ready to use system.
-
I noticed a problem in DarkENGINE_Start(). The way it currently works is potentially dangerous, since the function won't return immediately if it can't open input.device or timer.device. It prints a message but continues executing, which can lead to a crash if the rest of the function depends on these devices being correctly opened.
You could share the implementation of deOpenDevice_Input and deOpenDevice_Timer so I can see what breaks them on AROS.
-
BSZili : Concerning the way the DarkENGINE_Start function work, I know this. it is "beta" ( like the rest of the Engine ;) ) that's why I didn't put a "quit" yet.
(I have not yet done the "error handler" system)
Currently, the function that uses the TimerDevice (MyGetSysTime) check if timer.device was correctly opened (in the function deOpenDevice_Timer() ).
Same result for the Input.device
It will be fixed in the future by "quitting" the application with a popup containing an error message if the device cannot be opened.
I'll check for "VMWare Player" if it work with WinXP.
-
Here are the 2 functions :
BOOL deOpenDevice_Input( void ){
BOOL mReturn = FALSE;
struct Message * mio_Message;
m_inputPort = MyCreateMsgPort();
if ( m_inputPort ){
m_inputsigflag = 1L << m_inputPort->mp_SigBit;
#if defined( __amigaos4__ )
m_inputRequest = ( struct IOStdReq * )MyCreateIORequest( m_inputPort, sizeof( struct IORequest ) );
#elif defined( __MORPHOS__ )
m_inputRequest = (struct IOStdReq * )CreateExtIO( m_inputPort, sizeof( struct IOStdReq ) );
#elif defined( __AROS__ )
m_inputRequest = ( struct IOStdReq * )MyCreateIORequest( ( struct MstPort * )m_inputPort, (int)sizeof( struct IOStdReq ) );
mio_Message = &m_inputRequest->io_Message;
mio_Message->mn_Length = (ULONG)sizeof( m_inputRequest );
#endif
if ( m_inputRequest ){
if ( MyOpenDevice( "input.device", 0, (struct IORequest *)m_inputRequest, 0 ) ){
#if defined( __amigaos4__ )
InputBase = m_inputRequest->io_Device;
m_IInput = (struct InputIFace *)MyGetInterface( ( struct Library *)InputBase, "main", 0 );
#endif
mReturn = TRUE;
}
}
}
return mReturn;
}
BOOL deOpenDevice_Timer( void ){
BOOL mReturn = FALSE;
timerPort = MyCreateMsgPort();
if ( timerPort ){
timersigflag = 1 << timerPort->mp_SigBit;
#if defined( __amigaos4__ )
timerRequest = ( struct TimeRequest * )MyCreateIORequest( timerPort, sizeof( struct TimeRequest ) );
#elif defined( __MORPHOS__ )
timerRequest = (struct timerequest *)CreateExtIO( timerPort, sizeof( struct timerequest ) );
#elif defined( __AROS__ )
timerRequest = CreateExtIO( timerPort, sizeof( struct timerequest ) );
#endif
if ( timerRequest ){
if ( MyOpenDevice( "timer.device", UNIT_MICROHZ, (struct IORequest *)timerRequest, 0 ) ){
#if defined( __amigaos4__ )
TimerBase = timerRequest->Request.io_Device;
ITimer = (struct TimerIFace *)MyGetInterface( ( struct Library *)TimerBase, "main", 1 );
#endif
MyGetSysTime( MyTimeVal );
timerFirst = TRUE;
#if defined( __amigaos4__ )
NewTimer = ( MyTimeVal->Seconds * 1000000 ) + MyTimeVal->Microseconds;
#else
NewTimer = ( MyTimeVal->tv_secs * 1000000 ) + MyTimeVal->tv_micro;
#endif
OldTimer = NewTimer;
DemoStartTimer = NewTimer;
mReturn = TRUE;
}
}
}
return mReturn;
}
-
Ok, I didn't know you have had error handling somewhere else. Thanks for the code, I'll write a small test program to figure out why they wouldn't work. I see there MyCreateIORequest and CreateExtIO used interchangeably. Does MyCreateIORequest use CreateExtIO internally? I have the same question about MyCreateMsgPort, I presume it's a wrapper around CreateMsgPort.
-
Yes, they're wrapper :
struct IORequest * MyCreateIORequest( struct MsgPort * MyIOPort, int SizeRequest ){
struct IORequest * MyIORequest;
#if defined( __amigaos4__ )
MyIORequest= IExec->CreateIORequest( MyIOPort, SizeRequest );
#else
MyIORequest = CreateIORequest( MyIOPort, SizeRequest );
#endif
return MyIORequest;
}
struct MsgPort * MyCreateMsgPort( void ){
struct MsgPort * MyMessagePort;
#if defined( __amigaos4__ )
MyMessagePort = IExec->CreateMsgPort();
#else
MyMessagePort = CreateMsgPort();
#endif
return MyMessagePort;
}
-
While that's a perfectly sound way of doing it, if you want to avoid wrapper functions like that, you can define __USE_INLINE__ on AmigaOS4. That will define you a bunch of compatibility macros, so you can use CreateMsgPort instead of IExec->CreateMsgPort.
Back to the AROS. This code doesn't look right to me:
if ( MyOpenDevice( "input.device", 0, (struct IORequest *)m_inputRequest, 0 ) ){
#if defined( __amigaos4__ )
InputBase = m_inputRequest->io_Device;
m_IInput = (struct InputIFace *)MyGetInterface( ( struct Library *)InputBase, "main", 0 );
#endif
mReturn = TRUE;
}
Unless you changed that in MyOpendevice, OpenDevice returns 0 if the device was opened successfully and an != 0 error code if it failed.
The second problem is InputBase. You only set it on AmigaOS4, which means it will be uninitialized on other platforms, unless a library auto-opener does it for you. Since you are already opening input.device, InputBase should be always initialized.
The same goes for TimerBase, the initializer function most likely segfaults on the first GetSysTime call, because TimerBase is not initialized, and holds a random value.
-
Yes, I know that.
But, it exists few commands/functions in the AmigaOS4 that do not exist on other Amiga OSes and that need to be developed differently.
That's why I decided to keep this form. To be sure I never lose focus on AmigaOS4 specific commands/functions and other OSes ones ;)
-
What about the second part of my post? E.g. the return value of OpenDevice, TimerBase and InputBase not being set, etc.
-
I'll check these.