]> git.sesse.net Git - vlc/blobdiff - src/interface/main.c
* ALL: got rid of *_Probe functions because most of them were duplicates
[vlc] / src / interface / main.c
index b1c9850e75db671075cafd3d05abf67eb7b856ee..4953e511aa2771a950bab9ad625fc350c1f33c75 100644 (file)
@@ -4,7 +4,7 @@
  * and spawn threads.
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: main.c,v 1.135 2001/12/10 13:17:35 sam Exp $
+ * $Id: main.c,v 1.151 2002/02/15 13:32:54 sam Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include "defs.h"
-
 #include <signal.h>                               /* SIGHUP, SIGINT, SIGKILL */
 #include <stdio.h>                                              /* sprintf() */
 #include <setjmp.h>                                       /* longjmp, setjmp */
 
+#include <videolan/vlc.h>
+
 #ifdef HAVE_GETOPT_LONG
 #   ifdef HAVE_GETOPT_H
 #       include <getopt.h>                                       /* getopt() */
 #   include <io.h>
 #endif
 
+#ifdef HAVE_LOCALE_H
+#    include <locale.h>
+#endif
+
 #include <errno.h>                                                 /* ENOMEM */
 #include <stdlib.h>                                  /* getenv(), strtol(),  */
 #include <string.h>                                            /* strerror() */
 #include <fcntl.h>                                       /* open(), O_WRONLY */
 #include <sys/stat.h>                                             /* S_IREAD */
 
-#include "common.h"
-#include "debug.h"
-#include "intf_msg.h"
-#include "threads.h"
-#include "mtime.h"
-#include "tests.h"                                              /* TestCPU() */
-#include "modules.h"
+#include "netutils.h"                                 /* network_ChannelJoin */
 
 #include "stream_control.h"
 #include "input_ext-intf.h"
 #include "video.h"
 #include "video_output.h"
 
-#ifdef SYS_BEOS
-#   include "beos_specific.h"
-#endif
-
-#ifdef SYS_DARWIN
-#   include "darwin_specific.h"
-#endif
-
-#ifdef WIN32
-#   include "win32_specific.h"
-#endif
-
-#include "netutils.h"                                 /* network_ChannelJoin */
+#include "debug.h"
 
 /*****************************************************************************
  * Command line options constants. If something is changed here, be sure that
 #define OPT_HEIGHT              163
 #define OPT_COLOR               164
 #define OPT_FULLSCREEN          165
-#define OPT_OVERLAY             166
+#define OPT_NOOVERLAY           166
 #define OPT_XVADAPTOR           167
 #define OPT_SMP                 168
+#define OPT_SPUMARGIN           169
 
 #define OPT_CHANNELS            170
 #define OPT_SERVER              171
 #define OPT_DOWNMIX             184
 #define OPT_IMDCT               185
 #define OPT_MEMCPY              186
-#define OPT_DVDCSS_METHOD       187
-#define OPT_DVDCSS_VERBOSE      188
+#define OPT_FILTER              187
+#define OPT_DVDCSS_METHOD       188
+#define OPT_DVDCSS_VERBOSE      189
 
 #define OPT_SYNCHRO             190
 #define OPT_WARNING             191
 #define OPT_STATS               194
 
 #define OPT_MPEG_ADEC           200
+#define OPT_AC3_ADEC            201
+
+#define OPT_NOMMX               210
+#define OPT_NO3DNOW             211
+#define OPT_NOMMXEXT            212
+#define OPT_NOSSE               213
+#define OPT_NOALTIVEC           214
 
 /* Usage fashion */
 #define USAGE                     0
 #define SHORT_HELP                1
 #define LONG_HELP                 2
 
-/* Needed for x86 CPU capabilities detection */
-#define cpuid( a )                 \
-    asm volatile ( "cpuid"         \
-                 : "=a" ( i_eax ), \
-                   "=b" ( i_ebx ), \
-                   "=c" ( i_ecx ), \
-                   "=d" ( i_edx )  \
-                 : "a"  ( a )      \
-                 : "cc" );
-
 /* Long options */
 static const struct option longopts[] =
 {
@@ -199,9 +184,10 @@ static const struct option longopts[] =
     {   "idct",             1,          0,      OPT_IDCT },
     {   "yuv",              1,          0,      OPT_YUV },
     {   "fullscreen",       0,          0,      OPT_FULLSCREEN },
-    {   "overlay",          0,          0,      OPT_OVERLAY },
+    {   "nooverlay",        0,          0,      OPT_NOOVERLAY },
     {   "xvadaptor",        1,          0,      OPT_XVADAPTOR },
     {   "smp",              1,          0,      OPT_SMP },
+    {   "spumargin",        1,          0,      OPT_SPUMARGIN },
 
     /* DVD options */
     {   "dvdtitle",         1,          0,      't' },
@@ -212,7 +198,7 @@ static const struct option longopts[] =
     {   "dvdsubtitle",      1,          0,      's' },
     {   "dvdcss-method",    1,          0,      OPT_DVDCSS_METHOD },
     {   "dvdcss-verbose",   1,          0,      OPT_DVDCSS_VERBOSE },
-    
+
     /* Input options */
     {   "input",            1,          0,      OPT_INPUT },
     {   "channels",         0,          0,      OPT_CHANNELS },
@@ -221,9 +207,18 @@ static const struct option longopts[] =
     /* Misc options */
     {   "synchro",          1,          0,      OPT_SYNCHRO },
     {   "memcpy",           1,          0,      OPT_MEMCPY },
+    {   "filter",           1,          0,      OPT_FILTER },
 
     /* Decoder options */
     {   "mpeg_adec",        1,          0,      OPT_MPEG_ADEC },
+    {   "ac3_adec",         1,          0,      OPT_AC3_ADEC },
+
+    /* CPU options */
+    {   "nommx",            0,          0,      OPT_NOMMX },
+    {   "no3dnow",          0,          0,      OPT_NO3DNOW },
+    {   "nommxext",         0,          0,      OPT_NOMMXEXT },
+    {   "nosse",            0,          0,      OPT_NOSSE },
+    {   "noaltivec",        0,          0,      OPT_NOALTIVEC },
 
     {   0,                  0,          0,      0 }
 };
@@ -236,6 +231,7 @@ static const char *psz_shortopts = "hHvgt:T:u:a:s:c:I:A:V:";
  *****************************************************************************/
 main_t        *p_main;
 module_bank_t *p_module_bank;
+input_bank_t  *p_input_bank;
 aout_bank_t   *p_aout_bank;
 vout_bank_t   *p_vout_bank;
 
@@ -251,14 +247,15 @@ static void Version                 ( void );
 static void InitSignalHandler       ( void );
 static void SimpleSignalHandler     ( int i_signal );
 static void FatalSignalHandler      ( int i_signal );
-static void InstructionSignalHandler( int i_signal );
-static int  CPUCapabilities         ( void );
+static void IllegalSignalHandler    ( int i_signal );
+static u32  CPUCapabilities         ( void );
 
 static int  RedirectSTDOUT          ( void );
 static void ShowConsole             ( void );
 
 static jmp_buf env;
-static int  i_illegal;
+static int     i_illegal;
+static char   *psz_capability;
 
 /*****************************************************************************
  * main: parse command line, start interface and spawn threads
@@ -274,24 +271,28 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
 {
     main_t        main_data;                /* root of all data - see main.h */
     module_bank_t module_bank;
+    input_bank_t  input_bank;
     aout_bank_t   aout_bank;
     vout_bank_t   vout_bank;
 
     p_main        = &main_data;               /* set up the global variables */
     p_module_bank = &module_bank;
+    p_input_bank  = &input_bank;
     p_aout_bank   = &aout_bank;
     p_vout_bank   = &vout_bank;
 
-#ifdef ENABLE_NLS
-    /* 
+#if defined( ENABLE_NLS ) && defined ( HAVE_GETTEXT )
+    /*
      * Support for getext
      */
-    if( ! setlocale(LC_MESSAGES, "") )
+#if defined( HAVE_LOCALE_H ) && defined( HAVE_LC_MESSAGES )
+    if( !setlocale( LC_MESSAGES, "" ) )
     {
         fprintf( stderr, "warning: unsupported locale.\n" );
     }
+#endif
 
-    if( ! bindtextdomain(PACKAGE, LOCALEDIR) )
+    if( !bindtextdomain( PACKAGE, LOCALEDIR ) )
     {
         fprintf( stderr, "warning: no domain %s in directory %s\n",
                  PACKAGE, LOCALEDIR );
@@ -299,17 +300,17 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
 
     textdomain( PACKAGE );
 #endif
-        
+
     /*
      * Initialize threads system
      */
     vlc_threads_init( );
 
     /*
-     * Test if our code is likely to run on this CPU 
+     * Test if our code is likely to run on this CPU
      */
     p_main->i_cpu_capabilities = CPUCapabilities();
-    
+
     /*
      * System specific initialization code
      */
@@ -372,7 +373,8 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
         PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
         PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
         PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "Altivec" );
-        intf_StatMsg("info: CPU has capabilities %s", p_capabilities );
+        PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
+        intf_StatMsg( "info: CPU has capabilities : %s", p_capabilities );
     }
 
     /*
@@ -393,28 +395,28 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
     GetFilenames( i_argc, ppsz_argv );
 
     /*
-     * Initialize module, aout and vout banks
+     * Initialize module, input, aout and vout banks
      */
     module_InitBank();
+    input_InitBank();
     aout_InitBank();
     vout_InitBank();
 
     /*
      * Choose the best memcpy module
      */
-    p_main->p_memcpy_module = module_Need( MODULE_CAPABILITY_MEMCPY, NULL );
-
-    if( p_main->p_memcpy_module != NULL )
+    p_main->p_memcpy_module = module_Need( MODULE_CAPABILITY_MEMCPY, NULL,
+                                           NULL );
+    if( p_main->p_memcpy_module == NULL )
     {
-#define f p_main->p_memcpy_module->p_functions->memcpy.functions.memcpy
-        p_main->fast_memcpy = f.fast_memcpy;
-#undef f
+        intf_ErrMsg( "intf error: no suitable memcpy module, "
+                     "using libc default" );
+        p_main->pf_memcpy = memcpy;
     }
     else
     {
-        intf_ErrMsg( "intf error: no suitable memcpy module, "
-                     "using libc default" );
-        p_main->fast_memcpy = memcpy;
+        p_main->pf_memcpy = p_main->p_memcpy_module->p_functions
+                                  ->memcpy.functions.memcpy.pf_memcpy;
     }
 
     /*
@@ -425,8 +427,8 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
         network_ChannelCreate() )
     {
         /* On error during Channels initialization, switch off channels */
-        intf_Msg( "Channels initialization failed : "
-                  "Channel management is deactivated" );
+        intf_ErrMsg( "intf error: channels initialization failed, " 
+                                 "deactivating channels" );
         main_PutIntVariable( INPUT_NETWORK_CHANNEL_VAR, 0 );
     }
 
@@ -466,7 +468,19 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
     }
 
     /*
-     * Free memcpy module
+     * Free input, aout and vout banks
+     */
+    input_EndBank();
+    vout_EndBank();
+    aout_EndBank();
+
+    /*
+     * Free playlist
+     */
+    intf_PlaylistDestroy( p_main->p_playlist );
+
+    /*
+     * Free memcpy module if it was allocated
      */
     if( p_main->p_memcpy_module != NULL )
     {
@@ -474,17 +488,10 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
     }
 
     /*
-     * Free module, aout and vout banks
+     * Free module bank
      */
-    vout_EndBank();
-    aout_EndBank();
     module_EndBank();
 
-    /*
-     * Free playlist
-     */
-    intf_PlaylistDestroy( p_main->p_playlist );
-
     /*
      * System specific cleaning code
      */
@@ -496,7 +503,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
     /*
      * Terminate messages interface and program
      */
-    intf_Msg( "intf: program terminated" );
+    intf_WarnMsg( 1, "intf: program terminated" );
     intf_MsgDestroy();
 
     /*
@@ -753,7 +760,7 @@ static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] )
             main_PutIntVariable( AOUT_VOLUME_VAR, atoi(optarg) );
             break;
         case OPT_DESYNC:                                         /* --desync */
-            p_main->i_desync = atoi(optarg);
+            p_main->i_desync = (mtime_t)atoi(optarg) * (mtime_t)1000;
             break;
 
         /* Video options */
@@ -781,8 +788,8 @@ static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] )
         case OPT_FULLSCREEN:                                 /* --fullscreen */
             main_PutIntVariable( VOUT_FULLSCREEN_VAR, 1 );
             break;
-        case OPT_OVERLAY:                                       /* --overlay */
-            main_PutIntVariable( VOUT_OVERLAY_VAR, 1 );
+        case OPT_NOOVERLAY:                                   /* --nooverlay */
+            main_PutIntVariable( VOUT_NOOVERLAY_VAR, 1 );
             break;
         case OPT_XVADAPTOR:                                   /* --xvadaptor */
             main_PutIntVariable( VOUT_XVADAPTOR_VAR, atoi(optarg) );
@@ -799,6 +806,9 @@ static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] )
         case OPT_SMP:                                               /* --smp */
             main_PutIntVariable( VDEC_SMP_VAR, atoi(optarg) );
             break;
+        case OPT_SPUMARGIN:                                   /* --spumargin */
+            main_PutIntVariable( VOUT_SPUMARGIN_VAR, atoi(optarg) );
+            break;
 
         /* DVD options */
         case 't':                                              /* --dvdtitle */
@@ -845,18 +855,46 @@ static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] )
             break;
 
         /* Misc options */
-        case OPT_SYNCHRO:                                      
+        case OPT_SYNCHRO:
             main_PutPszVariable( VPAR_SYNCHRO_VAR, optarg );
             break;
-        case OPT_MEMCPY:                                      
+        case OPT_MEMCPY:
             main_PutPszVariable( MEMCPY_METHOD_VAR, optarg );
             break;
-            
+        case OPT_FILTER:                                         /* --filter */
+            main_PutPszVariable( VOUT_FILTER_VAR, optarg );
+            break;
+
         /* Decoder options */
         case OPT_MPEG_ADEC:
             main_PutPszVariable( ADEC_MPEG_VAR, optarg );
             break;
 
+        case OPT_AC3_ADEC:
+            main_PutPszVariable( ADEC_AC3_VAR, optarg );
+            break;
+
+        /* CPU options */
+        case OPT_NOMMX:
+            p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMX;
+            break;
+
+        case OPT_NO3DNOW:
+            p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_3DNOW;
+            break;
+
+        case OPT_NOMMXEXT:
+            p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMXEXT;
+            break;
+
+        case OPT_NOSSE:
+            p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_SSE;
+            break;
+
+        case OPT_NOALTIVEC:
+            p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_ALTIVEC;
+            break;
+
         /* Internal error: unknown option */
         case '?':
         default:
@@ -946,7 +984,7 @@ static void Usage( int i_fashion )
           "\n      --width <w>, --height <h>  \tdisplay dimensions"
           "\n  -g, --grayscale                \tgrayscale output"
           "\n      --fullscreen               \tfullscreen output"
-          "\n      --overlay                  \taccelerated display"
+          "\n      --nooverlay                \tdisable accelerated display"
           "\n      --xvadaptor <adaptor>      \tXVideo adaptor"
           "\n      --color                    \tcolor output"
           "\n      --motion <module>          \tmotion compensation method"
@@ -954,6 +992,8 @@ static void Usage( int i_fashion )
           "\n      --yuv <module>             \tYUV method"
           "\n      --synchro <type>           \tforce synchro algorithm"
           "\n      --smp <number of threads>  \tuse several processors"
+          "\n      --spumargin <m>            \tforce SPU position"
+          "\n      --filter <module>          \tvideo filter module"
           "\n"
           "\n  -t, --dvdtitle <num>           \tchoose DVD title"
           "\n  -T, --dvdchapter <num>         \tchoose DVD chapter"
@@ -968,12 +1008,19 @@ static void Usage( int i_fashion )
           "\n      --channels                 \tenable channels"
           "\n      --channelserver <host>     \tchannel server address"
           "\n"
-          "\n      --mpeg_adec <builtin|mad>  \tchoose audio decoder"
+          "\n      --mpeg_adec <builtin|mad>  \tchoose MPEG audio decoder"
+          "\n      --ac3_adec <builtin|a52>   \tchoose AC3 audio decoder"
+          "\n"
+          "\n      --nommx                    \tdisable CPU's MMX support"
+          "\n      --no3dnow                  \tdisable CPU's 3D Now! support"
+          "\n      --nommxext                 \tdisable CPU's MMX EXT support"
+          "\n      --nosse                    \tdisable CPU's SSE support"
+          "\n      --noaltivec                \tdisable CPU's AltiVec support"
           "\n"
           "\n  -h, --help                     \tprint help and exit"
           "\n  -H, --longhelp                 \tprint long help and exit"
           "\n      --version                  \toutput version information and exit"
-          "\n\nPlaylist items :"
+          "\n\nPlaylist items:"
           "\n  *.mpg, *.vob                   \tPlain MPEG-1/2 files"
           "\n  dvd:<device>[@<raw device>]    \tDVD device"
           "\n  vcd:<device>                   \tVCD device"
@@ -1014,13 +1061,15 @@ static void Usage( int i_fashion )
         "\n  " VOUT_FB_DEV_VAR "=<filename>           \tframebuffer device path"
         "\n  " VOUT_GRAYSCALE_VAR "={1|0}             \tgrayscale or color output"
         "\n  " VOUT_FULLSCREEN_VAR "={1|0}            \tfullscreen"
-        "\n  " VOUT_OVERLAY_VAR "={1|0}               \toverlay"
+        "\n  " VOUT_NOOVERLAY_VAR "={1|0}             \tnooverlay"
         "\n  " VOUT_XVADAPTOR_VAR "=<adaptor>         \tXVideo adaptor"
         "\n  " MOTION_METHOD_VAR "=<method name>      \tmotion compensation method"
         "\n  " IDCT_METHOD_VAR "=<method name>        \tIDCT method"
         "\n  " YUV_METHOD_VAR "=<method name>         \tYUV method"
         "\n  " VPAR_SYNCHRO_VAR "={I|I+|IP|IP+|IPB}   \tsynchro algorithm"
-        "\n  " VDEC_SMP_VAR "=<number of threads>     \tuse several processors" );
+        "\n  " VDEC_SMP_VAR "=<number of threads>     \tuse several processors"
+        "\n  " VOUT_FILTER_VAR "=<method name>        \tvideo filter method"
+        "\n  " VOUT_SPUMARGIN_VAR "=<margin>          \tforce SPU margin" );
 
     /* DVD parameters */
     intf_MsgImm( "\nDVD parameters:"
@@ -1040,7 +1089,8 @@ static void Usage( int i_fashion )
 
     /* Decoder parameters */
     intf_MsgImm( "\nDecoder parameters:"
-        "\n  " ADEC_MPEG_VAR "=<builtin|mad>          \taudio decoder" );
+        "\n  " ADEC_MPEG_VAR "=<builtin|mad>          \tMPEG audio decoder"
+        "\n  " ADEC_AC3_VAR "=<builtin|a52>           \tAC3 audio decoder" );
 }
 
 /*****************************************************************************
@@ -1078,7 +1128,6 @@ static void InitSignalHandler( void )
 #endif
 }
 
-
 /*****************************************************************************
  * SimpleSignalHandler: system signal handler
  *****************************************************************************
@@ -1090,7 +1139,6 @@ static void SimpleSignalHandler( int i_signal )
     intf_WarnMsg( 0, "intf: ignoring signal %d", i_signal );
 }
 
-
 /*****************************************************************************
  * FatalSignalHandler: system signal handler
  *****************************************************************************
@@ -1117,24 +1165,28 @@ static void FatalSignalHandler( int i_signal )
 }
 
 /*****************************************************************************
- * InstructionSignalHandler: system signal handler
+ * IllegalSignalHandler: system signal handler
  *****************************************************************************
  * This function is called when a illegal instruction signal is received by
- * the program.
- * We use this function to test OS and CPU_Capabilities
+ * the program. We use this function to test OS and CPU capabilities
  *****************************************************************************/
-static void InstructionSignalHandler( int i_signal )
+static void IllegalSignalHandler( int i_signal )
 {
-    /* Once a signal has been trapped, the termination sequence will be
-     * armed and following signals will be ignored to avoid sending messages
-     * to an interface having been destroyed */
-
     /* Acknowledge the signal received */
     i_illegal = 1;
-    
+
 #ifdef HAVE_SIGRELSE
     sigrelse( i_signal );
 #endif
+
+    fprintf( stderr, "warning: your CPU has %s instructions, but not your "
+                     "operating system.\n", psz_capability );
+    fprintf( stderr, "         some optimizations will be disabled unless "
+                     "you upgrade your OS\n" );
+#ifdef SYS_LINUX
+    fprintf( stderr, "         (for instance Linux kernel 2.4.x or later)" );
+#endif
+
     longjmp( env, 1 );
 }
 
@@ -1143,19 +1195,11 @@ static void InstructionSignalHandler( int i_signal )
  *****************************************************************************
  * This function is called to list extensions the CPU may have.
  *****************************************************************************/
-static int CPUCapabilities( void )
+static u32 CPUCapabilities( void )
 {
-    volatile int i_capabilities = CPU_CAPABILITY_NONE;
-
-#if defined( SYS_BEOS )
-    i_capabilities |= CPU_CAPABILITY_FPU
-                      | CPU_CAPABILITY_486
-                      | CPU_CAPABILITY_586
-                      | CPU_CAPABILITY_MMX;
-
-    return( i_capabilities );
+    volatile u32 i_capabilities = CPU_CAPABILITY_NONE;
 
-#elif defined( SYS_DARWIN )
+#if defined( SYS_DARWIN )
     struct host_basic_info hi;
     kern_return_t          ret;
     host_name_port_t       host;
@@ -1191,27 +1235,47 @@ static int CPUCapabilities( void )
     volatile unsigned int  i_eax, i_ebx, i_ecx, i_edx;
     volatile boolean_t     b_amd;
 
+    /* Needed for x86 CPU capabilities detection */
+#   define cpuid( a )                      \
+        asm volatile ( "pushl %%ebx\n\t"   \
+                       "cpuid\n\t"         \
+                       "movl %%ebx,%1\n\t" \
+                       "popl %%ebx\n\t"    \
+                     : "=a" ( i_eax ),     \
+                       "=r" ( i_ebx ),     \
+                       "=c" ( i_ecx ),     \
+                       "=d" ( i_edx )      \
+                     : "a"  ( a )          \
+                     : "cc" );
+
     i_capabilities |= CPU_CAPABILITY_FPU;
 
-    signal( SIGILL, InstructionSignalHandler );
-    
+#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
+    signal( SIGILL, IllegalSignalHandler );
+#   endif
+
     /* test for a 486 CPU */
-    asm volatile ( "pushfl\n\t"
+    asm volatile ( "pushl %%ebx\n\t"
+                   "pushfl\n\t"
                    "popl %%eax\n\t"
                    "movl %%eax, %%ebx\n\t"
                    "xorl $0x200000, %%eax\n\t"
                    "pushl %%eax\n\t"
                    "popfl\n\t"
                    "pushfl\n\t"
-                   "popl %%eax"
+                   "popl %%eax\n\t"
+                   "movl %%ebx,%1\n\t"
+                   "popl %%ebx\n\t"
                  : "=a" ( i_eax ),
-                   "=b" ( i_ebx )
+                   "=r" ( i_ebx )
                  :
                  : "cc" );
 
     if( i_eax == i_ebx )
     {
-        signal( SIGILL, NULL );     
+#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
+        signal( SIGILL, NULL );
+#   endif
         return( i_capabilities );
     }
 
@@ -1222,7 +1286,9 @@ static int CPUCapabilities( void )
 
     if( !i_eax )
     {
-        signal( SIGILL, NULL );     
+#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
+        signal( SIGILL, NULL );
+#   endif
         return( i_capabilities );
     }
 
@@ -1238,7 +1304,9 @@ static int CPUCapabilities( void )
 
     if( ! (i_edx & 0x00800000) )
     {
-        signal( SIGILL, NULL );     
+#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
+        signal( SIGILL, NULL );
+#   endif
         return( i_capabilities );
     }
 
@@ -1248,8 +1316,9 @@ static int CPUCapabilities( void )
     {
         i_capabilities |= CPU_CAPABILITY_MMXEXT;
 
-#ifdef CAN_COMPILE_SSE
+#   ifdef CAN_COMPILE_SSE
         /* We test if OS support the SSE instructions */
+        psz_capability = "SSE";
         i_illegal = 0;
         if( setjmp( env ) == 0 )
         {
@@ -1261,33 +1330,27 @@ static int CPUCapabilities( void )
         {
             i_capabilities |= CPU_CAPABILITY_SSE;
         }
-        else
-        {
-            fprintf( stderr, "warning: your OS doesn't have support for "
-                             "SSE instructions, "
-                             "some optimizations\nwill be disabled\n" );
-#ifdef SYS_LINUX
-            fprintf( stderr, "(you will need Linux kernel 2.4.x or later)\n" );
-#endif
-        }
-#endif
+#   endif
     }
-    
+
     /* test for additional capabilities */
     cpuid( 0x80000000 );
 
     if( i_eax < 0x80000001 )
     {
-        signal( SIGILL, NULL );     
+#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
+        signal( SIGILL, NULL );
+#   endif
         return( i_capabilities );
     }
 
     /* list these additional capabilities */
     cpuid( 0x80000001 );
 
-#ifdef CAN_COMPILE_3DNOW
+#   ifdef CAN_COMPILE_3DNOW
     if( i_edx & 0x80000000 )
     {
+        psz_capability = "3D Now!";
         i_illegal = 0;
         if( setjmp( env ) == 0 )
         {
@@ -1295,29 +1358,31 @@ static int CPUCapabilities( void )
             __asm__ __volatile__ ( "pfadd %%mm0,%%mm0\n" "femms\n" : : );
         }
 
-        if( i_illegal == 0 ) 
+        if( i_illegal == 0 )
         {
             i_capabilities |= CPU_CAPABILITY_3DNOW;
         }
     }
-#endif
+#   endif
 
     if( b_amd && ( i_edx & 0x00400000 ) )
     {
         i_capabilities |= CPU_CAPABILITY_MMXEXT;
     }
 
-    signal( SIGILL, NULL );     
+#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
+    signal( SIGILL, NULL );
+#   endif
     return( i_capabilities );
 
 #elif defined( __powerpc__ )
 
     i_capabilities |= CPU_CAPABILITY_FPU;
 
-    /* Test for Altivec */
-    signal( SIGILL, InstructionSignalHandler );
+#   ifdef CAN_COMPILE_ALTIVEC
+    signal( SIGILL, IllegalSignalHandler );
 
-#ifdef CAN_COMPILE_ALTIVEC
+    psz_capability = "AltiVec";
     i_illegal = 0;
     if( setjmp( env ) == 0 )
     {
@@ -1331,9 +1396,10 @@ static int CPUCapabilities( void )
     {
         i_capabilities |= CPU_CAPABILITY_ALTIVEC;
     }
-#endif
 
-    signal( SIGILL, NULL );     
+    signal( SIGILL, NULL );
+#   endif
+
     return( i_capabilities );
 
 #else
@@ -1401,4 +1467,3 @@ static void ShowConsole( void )
 #endif
     return;
 }
-