home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / CD32 / CD32-Tools / cdmpeg-110 / cdmpeg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-27  |  15.5 KB  |  732 lines

  1. /*******************
  2.       cdmpeg.c
  3.  
  4.     W.D.L 931014
  5. ********************/
  6.  
  7. /*
  8.  * COPYRIGHT: Unless otherwise noted, all files are Copyright (c) 1993-1999
  9.  * Amiga, Inc.  All rights reserved.
  10.  *
  11.  * DISCLAIMER: This software is provided "as is".  No representations or
  12.  * warranties are made with respect to the accuracy, reliability, performance,
  13.  * currentness, or operation of this software, and all use is at your own risk.
  14.  * Neither Amiga nor the authors assume any responsibility or liability
  15.  * whatsoever with respect to your use of this software.
  16.  */
  17.  
  18. // Tab size is 8!
  19.  
  20. #include <exec/types.h>
  21. #include <exec/memory.h>
  22.  
  23. #include <graphics/gfxbase.h>
  24.  
  25. #include <dos/dos.h>
  26. #include <intuition/intuition.h>
  27.  
  28. #include <libraries/lowlevel.h>
  29.  
  30. #include "devices/cd.h"
  31. #include <devices/mpeg.h>
  32.  
  33. #include <clib/exec_protos.h>
  34. #include <clib/dos_protos.h>
  35. #include <clib/graphics_protos.h>
  36. #include <clib/mpeg_protos.h>
  37. #include <clib/lowlevel_protos.h>
  38.  
  39. #include <pragmas/exec_pragmas.h>
  40. #include <pragmas/graphics_pragmas.h>
  41. #include <pragmas/realtime_pragmas.h>
  42. #include <pragmas/mpeg_pragmas.h>
  43. #include <pragmas/lowlevel_pragmas.h>
  44.  
  45.  
  46. #include "stdio.h"
  47. #include <stdlib.h>
  48. #include <math.h>    // For min() & max()
  49. #include <string.h>    // for setmem()
  50.  
  51. #include "disp_def.h"
  52. #include "retcodes.h"
  53. #include "cdmpeg.h"
  54.  
  55. #include "cdmpeg_rev.h"
  56.  
  57.  
  58. #include "debugsoff.h"
  59. #define        KPRINTF
  60. //#include "debugson.h"
  61.  
  62.  
  63. // argument parsing 
  64. #define TEMPLATE    "TRACK/A/N,BACK/K,LMBABORT/S,RMBABORT/S,FIREABORT/S,LACE/S,INFO/S" VERSTAG " Wayne D. Lutz"
  65. #define OPT_TRACK    0
  66. #define OPT_BACK    1
  67. #define    OPT_LMBABORT    2
  68. #define    OPT_RMBABORT    3
  69. #define    OPT_FIREABORT    4
  70. #define    OPT_LACE    5
  71. #define    OPT_INFO    6
  72. #define    OPT_COUNT    7
  73.  
  74.  
  75. LONG          opts[OPT_COUNT];
  76. struct RDArgs    * rdargs;
  77.  
  78. BOOL              DisplayIsPal;
  79.  
  80.  
  81. int CXBRK(void) { return(0); }        /* Disable SASC CTRL/C handling */
  82. int chkabort(void) { return(0); }    /* Indeed */
  83.  
  84. // Error messages.
  85. STATIC UBYTE * ErrorMsg[] = {
  86.     "No error",
  87.     "Error while reading file",
  88.     "Couldn't open file",
  89.     "Not enough memory for operation",
  90.     "Could not open cd/cdtv device",
  91.     "Could not open window",
  92.     "Could not open screen",
  93.     "BAD MPEG Track specification.\nTry the INFO command line argument to see track info.",
  94.     "Operation failed"
  95. };
  96.  
  97.  
  98. struct Library        * IntuitionBase;
  99. struct Library        * GfxBase;
  100. struct Library        * IFFParseBase;
  101. struct Library        * FreeAnimBase;
  102. struct Library        * LowLevelBase;
  103.  
  104. STATIC struct Device    * MPEGDevice;
  105. STATIC struct MsgPort    * MPEGPort;
  106. STATIC struct IOMPEGReq    * MPEGReq;
  107.  
  108. STATIC struct Device    * CDDevice;
  109. STATIC struct MsgPort    * CDPort;
  110. STATIC struct IOStdReq    * CDDeviceMReq;
  111.  
  112. IMPORT ULONG    CopSignal;
  113.  
  114. /*
  115.  * Close every thing down.
  116.  */
  117. STATIC VOID
  118. closedown( VOID )
  119. {
  120.     if ( IntuitionBase )
  121.     CloseLibrary( IntuitionBase );
  122.  
  123.     if ( GfxBase )
  124.     CloseLibrary( GfxBase );
  125.  
  126.     if ( IFFParseBase )
  127.     CloseLibrary( IFFParseBase );
  128.  
  129.     if ( FreeAnimBase )
  130.     CloseLibrary( FreeAnimBase );
  131.  
  132.     if ( LowLevelBase )
  133.     CloseLibrary( LowLevelBase );
  134.  
  135. } // closedown()
  136.  
  137.  
  138. /*
  139.  * Open all of the required libraries.
  140.  */
  141. STATIC
  142. init( BOOL iff )
  143. {
  144.     if ( !(IntuitionBase = OpenLibrary("intuition.library", 39L)) ) {
  145.     printf("Could NOT open intuition.library V39!\n");
  146.     return( RC_FAILED );
  147.     }
  148.  
  149.     if(!(GfxBase = OpenLibrary("graphics.library",39L)) ) {
  150.     printf("Could NOT open graphics.library V39!\n");
  151.     return( RC_FAILED );
  152.     }
  153.  
  154.     if(iff && !(IFFParseBase = OpenLibrary("iffparse.library",0L)) ) {
  155.     printf("Could NOT open iffparse.library!\n");
  156.         return( RC_FAILED );
  157.     }
  158.  
  159.     D(PRINTF("init() IFFParseBase= 0x%lx\n",IFFParseBase);)
  160.  
  161.     if ( !(LowLevelBase = OpenLibrary( "lowlevel.library", 40L )) ) {
  162.     printf("Could NOT open lowlevel.library!\n");
  163.     return( RC_FAILED );
  164.     }
  165.  
  166.     FreeAnimBase = OpenLibrary("freeanim.library",0L);
  167.  
  168.     return( RC_OK );
  169.  
  170. } // init()
  171.  
  172.  
  173. VOID
  174. MPEGDeviceTerm( VOID )
  175. {
  176.     if ( MPEGReq ) {
  177.     if ( MPEGDevice ) {
  178.         CloseDevice( (struct IORequest *)MPEGReq );
  179.         MPEGDevice = NULL;
  180.     }
  181.  
  182.     if ( MPEGPort ) {
  183.         while( GetMsg( MPEGPort ) );
  184.     }
  185.  
  186.     DeleteIORequest( MPEGReq );
  187.     MPEGReq = NULL;
  188.     }
  189.  
  190.     if ( MPEGPort ) {
  191.     DeleteMsgPort( MPEGPort );
  192.     MPEGPort = NULL;
  193.     }
  194.  
  195. } // MPEGDeviceTerm()
  196.  
  197.  
  198. /*
  199.  * Attempts to open cd32mpeg.device if not already opened.
  200.  * Returns:
  201.  *    retcode: (BOOL) reflects device's open state.
  202.  *  *opened: (BOOL) TRUE if opened by this call.
  203.  */
  204. BOOL
  205. MPEGDeviceInit( ULONG * opened )
  206. {
  207.  
  208.     if ( opened )
  209.     *opened = FALSE;
  210.  
  211.     if ( !MPEGDevice ) {
  212.     D(PRINTF("MPEGDeviceInit() have to prep MPEGDevice!");)
  213.  
  214.     if ( MPEGPort = CreateMsgPort() ) {
  215.         D(PRINTF("MPEGDeviceInit() GOT MPEGPort\n");)
  216.  
  217.         if ( MPEGReq = CreateIORequest( MPEGPort, sizeof (struct IOMPEGReq)) ) {
  218.         D(PRINTF("MPEGDeviceInit() GOT MPEGDeviceMReq\n");)
  219.  
  220.         if ( !OpenDevice( MPEG_NAME, 0, (struct IORequest *)MPEGReq, 0 ) ) {
  221.             D(PRINTF("MPEGDeviceInit() Got a Device\n");)
  222.             MPEGDevice = MPEGReq->iomr_Req.io_Device;
  223.         }
  224.         }
  225.     }
  226.  
  227.     if ( !MPEGDevice ) {
  228.         D(PRINTF("MPEGDeviceInit() Failed!! port 0x%lx request 0x%lx device 0x%lx\n",
  229.         MPEGPort, MPEGReq, MPEGDevice );)
  230.  
  231.         MPEGDeviceTerm();
  232.         return( FALSE );
  233.     }
  234.  
  235.     if ( opened )
  236.         *opened = TRUE;
  237.     }
  238.  
  239.     return( TRUE );    
  240.  
  241. } // MPEGDeviceInit()
  242.  
  243.  
  244. /*
  245.  * Close cd.device if opened.
  246.  */
  247. VOID
  248. CDDeviceTerm( VOID )
  249. {
  250.     if ( CDDeviceMReq ) {
  251.     if ( CDDevice ) {
  252.  
  253.         CloseDevice( (struct IORequest *)CDDeviceMReq );
  254.         CDDevice = NULL;
  255.     }
  256.  
  257.     if ( MPEGPort ) {
  258.         while( GetMsg( MPEGPort ) );
  259.     }
  260.  
  261.     DeleteStdIO( CDDeviceMReq );
  262.     CDDeviceMReq = NULL;
  263.     }
  264.  
  265.     if ( CDPort ) {
  266.     DeleteMsgPort( CDPort );
  267.     CDPort = NULL;
  268.     }
  269.  
  270. } // CDDeviceTerm()
  271.  
  272.  
  273. /*
  274.  * Attempts to open cd.device if not already opened.
  275.  * Returns:
  276.  *    retcode: (BOOL) reflects device's open state.
  277.  *  *opened: (BOOL) TRUE if opened by this call.
  278.  */
  279. BOOL
  280. CDDeviceInit( ULONG * opened )
  281. {
  282.     if ( opened )
  283.     *opened = FALSE;
  284.  
  285.     if ( !CDDevice ) {
  286.     D(PRINTF("CDDeviceInit() have to prep CDDevice!");)
  287.  
  288.     if ( CDPort = CreateMsgPort() ) {
  289.         D(PRINTF("CDDeviceInit() GOT CDPort\n");)
  290.         if ( CDDeviceMReq = CreateStdIO( CDPort ) ) {
  291.         D(PRINTF("CDDeviceInit() GOT CDDeviceMReq\n");)
  292.         // Try to open cd.device. If can't, try for cdtv.device.
  293.  
  294.         if ( !OpenDevice( CD_NAME, 0, (struct IORequest *)CDDeviceMReq, 0 ) ) {
  295.             D(PRINTF("CDDeviceInit() Got a Device\n");)
  296.             CDDevice = CDDeviceMReq->io_Device;
  297.         }
  298.         }
  299.     }
  300.  
  301.     if ( !CDDevice ) {
  302.         D(PRINTF("CDDeviceInit() Failed!! port 0x%lx request 0x%lx device 0x%lx\n",
  303.         CDPort, CDDeviceMReq, CDDevice );)
  304.  
  305.         CDDeviceTerm();
  306.         return( FALSE );
  307.     }
  308.  
  309.     if ( opened )
  310.         *opened = TRUE;
  311.     }
  312.  
  313.     return( TRUE );    
  314.  
  315. } // CDDeviceInit()
  316.  
  317.  
  318. /*
  319.  *  SendIOR -- asynchronously execute a device command
  320.  */
  321. BOOL
  322. SendIOR( struct IOStdReq * req, LONG cmd, ULONG off, ULONG len, APTR data)
  323. {
  324.     req->io_Command = cmd;
  325.     req->io_Offset = off;
  326.     req->io_Length = len;
  327.     req->io_Data   = data;
  328.  
  329.     SendIO( (struct IORequest *)req);
  330.  
  331.     if ( req->io_Error ) {
  332.     printf("SendIOR() ERROR!!! io_Error= %ld\n",req->io_Error);
  333.     kprintf("SendIOR() ERROR!!! io_Error= %ld\n",req->io_Error);
  334.     return( FALSE );
  335.     } else {
  336.     return( TRUE );
  337.     }
  338.  
  339. } // SendIOR()
  340.  
  341.  
  342. VOID
  343. DoBorder()
  344. {
  345. struct IOMPEGReq        req = *MPEGReq; // structure copy
  346. struct MPEGBorderParams  bp;
  347.  
  348.     if (req.iomr_Req.io_Device)
  349.     {
  350.         bp.mbp_BorderLeft  = 0;
  351.         bp.mbp_BorderTop   = 0;
  352.         bp.mbp_BorderRed   = 17;
  353.         bp.mbp_BorderGreen = 17;
  354.         bp.mbp_BorderBlue  = 17;
  355.  
  356.         req.iomr_Req.io_Command = MPEGCMD_SETBORDER;
  357.         req.iomr_Req.io_Data    = &bp;
  358.         req.iomr_Req.io_Length  = sizeof(bp);
  359.         req.iomr_Req.io_Offset  = 0;
  360.         DoIO((struct IORequest *)&req);
  361.     }
  362. }
  363.  
  364.  
  365. VOID
  366. DoSearch( int direction )
  367. {
  368.     struct IOMPEGReq    req = *MPEGReq;    // structure copy
  369.  
  370.     req.iomr_Arg1 = 1 * direction;
  371.     req.iomr_Arg2 = NULL;
  372.  
  373.     D(PRINTF("DoSearch direction= %ld\n",direction);)
  374.  
  375. //    SendIOR( (struct IOStdReq *)&req, MPEGCMD_SCAN, NULL, NULL, NULL );
  376.  
  377.     if ( SendIOR( (struct IOStdReq *)&req, MPEGCMD_SINGLESTEP, NULL, NULL, NULL ) )
  378.     WaitIO( (struct IORequest *)&req );
  379.  
  380.     D(PRINTF("DoSearch END\n\n");)
  381.  
  382. } // DoSearch()
  383.  
  384.  
  385. VOID
  386. DoPause( VOID )
  387. {
  388. STATIC    BOOL        Paused = FALSE;
  389.     struct IOMPEGReq    req = *MPEGReq;    // structure copy
  390.  
  391.     Paused = !Paused;
  392.  
  393.     req.iomr_Arg1 = Paused;
  394.     req.iomr_Arg2 = NULL;
  395.  
  396.     if ( SendIOR( (struct IOStdReq *)&req, MPEGCMD_PAUSE, NULL, NULL, NULL ) )
  397.     WaitIO( (struct IORequest *)&req );
  398.  
  399. } // DoPause()
  400.  
  401. #define S(MASK) (MASK & state )
  402.  
  403. BOOL
  404. ReadPort( ULONG flags )
  405. {
  406. STATIC ULONG    oldstate = 0;
  407.     ULONG     state;
  408.  
  409.     if ( flags & (MPEG_LMBABORT|MPEG_RMBABORT) )
  410.     state = ReadJoyPort( 0 );
  411.  
  412.     if ( flags & MPEG_LMBABORT ) {
  413.     if ( (JP_TYPE_MASK & state) == JP_TYPE_MOUSE) {
  414.         if (S(JPF_BTN2))
  415.         return( TRUE );
  416.     }
  417.     }
  418.  
  419.     if ( flags & MPEG_RMBABORT ) {
  420.     if ( (JP_TYPE_MASK & state) == JP_TYPE_MOUSE) {
  421.         if (S(JPF_BTN1))
  422.         return( TRUE );
  423.     }
  424.     }
  425.  
  426. #ifdef    OUTT    // [
  427.     if ( flags & MPEG_FIREABORT ) {
  428.     state = ReadJoyPort( 1 );
  429.  
  430.     if ( ((JP_TYPE_MASK & state) == JP_TYPE_GAMECTLR) || ((JP_TYPE_MASK & state) == JP_TYPE_JOYSTK) ) {
  431.         if (S(JPF_BTN2))
  432.         return( TRUE );
  433.     }
  434.     }
  435. #else        // ][
  436.  
  437.     state = ReadJoyPort( 1 );
  438.  
  439.     if ( flags & MPEG_FIREABORT ) {
  440.     if ( ((JP_TYPE_MASK & state) == JP_TYPE_GAMECTLR) || ((JP_TYPE_MASK & state) == JP_TYPE_JOYSTK) ) {
  441.         if (S(JPF_BTN2))
  442.         return( TRUE );
  443.     }
  444.     }
  445.  
  446.     if ( S(JPF_BUTTON_PLAY) && (state != oldstate) )
  447.     DoPause();
  448. /*
  449.     if ( S(JPF_BUTTON_FORWARD) ) {
  450.     DoSearch( 1 );
  451.     } else if ( S(JPF_BUTTON_REVERSE) ) {
  452.     DoSearch( -1 );
  453.     }
  454. */
  455. #endif        // ]
  456.  
  457.     oldstate = state;
  458.  
  459.     return( FALSE );
  460.  
  461. } // ReadPort()
  462.  
  463.  
  464. VOID
  465. DumpTOC( union CDTOC * toc, int len )
  466. {
  467.     int    i;
  468.  
  469.     printf("FirstTrack= %ld, LastTrack= %ld, LeadOut LSN= %ld\n",
  470.     toc[0].Summary.FirstTrack,toc[0].Summary.LastTrack,
  471.     toc[0].Summary.LeadOut.LSN);
  472.  
  473.     len = MIN (len,(toc[0].Summary.LastTrack+1));
  474.  
  475.     for ( i = toc[0].Summary.FirstTrack; i < len; i++ ) {
  476.     printf("%ld: Track #%ld, Position LSN= %ld, CtlAdr= %ld\n",
  477.         i,toc[i].Entry.Track,toc[i].Entry.Position.LSN,
  478.         toc[i].Entry.CtlAdr);
  479.     }
  480.  
  481. } // DumpTOC()
  482.  
  483.  
  484. PlayMPEG( ULONG track, ULONG flags )
  485. {
  486.     union CDTOC            * toc;
  487.     struct MPEGVideoParamsSet      mvp;
  488.     ULONG              signalMask,mpegsig,signals;
  489.     int                  len,ret;
  490.     BOOL              done;
  491.  
  492.     len = 100;
  493.  
  494.     if ( !(toc = AllocVec ((len+1) * sizeof (union CDTOC), MEMF_CLEAR)) )
  495.     return( RC_NO_MEM );
  496.  
  497.     ret = SendIOR( CDDeviceMReq, CD_TOCLSN, NULL, len, toc );
  498.  
  499.     if ( !ret ) {
  500.     ret = RC_FAILED;
  501.     printf("Could NOT get TOC!\n");
  502.     goto exit;
  503.     }
  504.     WaitIO( (struct IORequest *)CDDeviceMReq );
  505.  
  506.     if ( flags & MPEG_INFO )
  507.     DumpTOC( toc, len );
  508.  
  509.     if ( (track <  toc[0].Summary.FirstTrack) || (track > toc[0].Summary.LastTrack) ) {
  510.     ret = RC_BAD_TRACK;
  511.     goto exit;
  512.     }
  513.     toc[toc[0].Summary.LastTrack + 1].Entry.Position.LSN = toc[0].Summary.LeadOut.LSN;
  514.  
  515.     MPEGReq->iomr_StreamType = MPEGSTREAM_SYSTEM;
  516.     mvp.mvp_Fade = 65535;    // Fade level.  0 = no MPEG video at all, 65535 = full saturation
  517.     mvp.mvp_DisplayType = 0;    // DisplayIsPal ? 3 : 4;    // 3 = PAL (50Hz), 4 = NTSC (60Hz)
  518.  
  519.     ret = SendIOR( (struct IOStdReq *)MPEGReq, MPEGCMD_SETVIDEOPARAMS, NULL,
  520.     sizeof (struct MPEGVideoParamsSet), &mvp );
  521.  
  522.     if ( !ret ) {
  523.     ret = RC_FAILED;
  524.     printf("Could NOT SETVIDEOPARAMS!\n");
  525.     printf("iomr_MPEGError= %ld\n",MPEGReq->iomr_MPEGError);
  526.     goto exit;
  527.     }
  528.     WaitIO( (struct IORequest *)MPEGReq );
  529.  
  530.     /* Set MPEG border position and color */
  531.     DoBorder();
  532.  
  533.     MPEGReq->iomr_MPEGFlags = 0;
  534.     MPEGReq->iomr_StreamType = MPEGSTREAM_SYSTEM;
  535.     MPEGReq->iomr_SectorSize = 2328;
  536.     MPEGReq->iomr_StreamStart = toc[track].Entry.Position.LSN;
  537.  
  538.     ret = SendIOR( (struct IOStdReq *)MPEGReq, MPEGCMD_PLAYLSN,
  539.     toc[track].Entry.Position.LSN,
  540.     toc[track + 1].Entry.Position.LSN - toc[track].Entry.Position.LSN,
  541.     NULL );
  542.  
  543.     if ( !ret ) {
  544.     ret = RC_FAILED;
  545.     printf("Could NOT PLAYLSN!\n");
  546.     printf("iomr_MPEGError= %ld\n",MPEGReq->iomr_MPEGError);
  547.     goto exit;
  548.     }
  549.     ret = RC_OK;
  550.  
  551.     mpegsig = 1L << MPEGPort->mp_SigBit;
  552.  
  553.     signalMask = SIGBREAKF_CTRL_C | mpegsig | CopSignal;
  554.  
  555.     done = FALSE;
  556.     while ( !done ) {
  557.  
  558.     signals = Wait( signalMask );
  559.  
  560.     if ( GetMsg( MPEGPort ) ) {
  561.         D(PRINTF("Got Msg from MPEGPort\n");)
  562.         done = TRUE;
  563.     }
  564.  
  565.     if ( signals & SIGBREAKF_CTRL_C ) {
  566.         D(PRINTF("GOT a CTRL_C\n");)
  567.         if ( !CheckIO( (struct IORequest *)MPEGReq ) ) {
  568.         D(PRINTF("Aborting!!\n");)
  569.         AbortIO( (struct IORequest *)MPEGReq );
  570.         WaitIO( (struct IORequest *)MPEGReq );
  571.         }
  572.         done = TRUE;
  573.     }
  574.  
  575.     if ( signals & CopSignal ) {
  576.         if ( flags & MPEG_BUTTONABORTMASK ) {
  577.         if ( ReadPort( flags ) ) {
  578.             D(PRINTF("Button Aborting!!\n");)
  579.             if ( !CheckIO( (struct IORequest *)MPEGReq ) ) {
  580.             D(PRINTF("Aborting!!\n");)
  581.             AbortIO( (struct IORequest *)MPEGReq );
  582.             WaitIO( (struct IORequest *)MPEGReq );
  583.             }
  584.             done = TRUE;
  585.         }
  586.         }
  587.     }
  588.  
  589.     }
  590.  
  591.     if ( SendIOR( (struct IOStdReq *)MPEGReq, CMD_FLUSH, NULL, NULL, NULL ) ) {
  592.     WaitIO( (struct IORequest *)MPEGReq );
  593.     }
  594.  
  595. exit:
  596.  
  597.     FreeVec( toc );
  598.  
  599.     return( ret );
  600.  
  601. } // PlayMPEG()
  602.  
  603.  
  604. VOID
  605. main( LONG argc,char * argv[] )
  606. {
  607.     UBYTE        * ilbmfile;
  608.     ULONG          track,flags = NULL;
  609.     struct DisplayInfo      disp;
  610.     int              ret;
  611.     DISP_DEF          disp_def ;
  612.  
  613.     // workbench
  614.     if ( argc == 0 )
  615.     exit( RETURN_ERROR );
  616.  
  617.     setmem( opts, sizeof (opts) ,0 );
  618.  
  619.     rdargs = ReadArgs(TEMPLATE, opts, NULL);
  620.  
  621.     if ( !rdargs ) {
  622.     PrintFault(IoErr(), NULL);
  623.     exit( RETURN_ERROR );
  624.     }
  625.  
  626.     ilbmfile = (UBYTE *)opts[OPT_BACK];
  627.     track = *(ULONG *)opts[OPT_TRACK];
  628.  
  629.     if ( ret = init( ilbmfile ? TRUE : FALSE ) ) {
  630.     closedown();
  631.     exit( RETURN_FAIL );
  632.     }
  633.  
  634.     setmem( &disp_def, sizeof (DISP_DEF) ,0 );
  635.  
  636.     disp_def.Flags |= DISP_SCREEN|DISP_NOPOINTER|DISP_COP_INT;
  637.  
  638.     if ( ilbmfile ) {
  639.     disp_def.Flags |= (DISP_INTERLEAVED|DISP_BACKGROUND|DISP_ALLOCBM);
  640.  
  641.     // Query the ILBM to find what sort of display to open.
  642.     if ( !DoQuery( ilbmfile, &disp_def ) ) {
  643.         ret = RC_CANT_FIND;
  644.         PF("main RC_CANT_FIND");
  645.         closedown();
  646.         exit( RETURN_FAIL );
  647.     }
  648.  
  649.     } else {
  650.     disp_def.Width = 320;
  651.     disp_def.Depth = 1;
  652.  
  653.     if ( opts[OPT_LACE] ) {
  654.         disp_def.Height = 400;
  655.         disp_def.ModeID = LORESLACE_KEY;
  656.     } else {
  657.         disp_def.Height = 200;
  658.         disp_def.ModeID = LORES_KEY;
  659.     }
  660.     }
  661.  
  662.     D(PRINTF("ilbmfile= '%ls'\n", PFSTR(ilbmfile) );)
  663.  
  664.     DisplayIsPal = FALSE;
  665.     if ( GetDisplayInfoData(NULL, (UBYTE *)&disp, sizeof(struct DisplayInfo), DTAG_DISP, LORES_KEY) ) {
  666.     if ( disp.PropertyFlags & DIPF_IS_PAL )
  667.         DisplayIsPal = TRUE;
  668.     }
  669.  
  670.     D(PRINTF("display type= '%ls', gfxbase says '%ls' - '%ls'\n",
  671.     DisplayIsPal ? "PAL" : "NTSC",
  672.     (GfxBase->DisplayFlags & PAL) ? "PAL" : "NTSC",
  673.     (GfxBase->DisplayFlags & REALLY_PAL) ? "REALLY_PAL" : "REALLY_NTSC" );)
  674.  
  675.     D(PRINTF("After Query disp_def.Width= %ld, Height= %ld\n",
  676.     disp_def.Width,disp_def.Height);)
  677.  
  678.     if ( opts[OPT_LMBABORT] )
  679.     flags |= MPEG_LMBABORT;
  680.  
  681.     if ( opts[OPT_RMBABORT] )
  682.     flags |= MPEG_RMBABORT;
  683.  
  684.     if ( opts[OPT_FIREABORT] )
  685.     flags |= MPEG_FIREABORT;
  686.  
  687.     if ( opts[OPT_INFO] )
  688.     flags |= MPEG_INFO;
  689.  
  690.     CDDeviceInit( NULL );
  691.     MPEGDeviceInit( NULL );
  692.  
  693.     if ( !(CDDeviceMReq && MPEGReq) ) {
  694. //    ret = RC_FAILED;
  695.     ret = RC_OK;    // So no error messages are printed to the console
  696.     goto exit;
  697.     }
  698.  
  699.     D(PRINTF("\nCDDeviceMReq= 0x%lx, MPEGReq= 0x%lx\n",
  700.     CDDeviceMReq,MPEGReq);)
  701.  
  702.     CloseLibrary( FreeAnimBase );
  703.     FreeAnimBase = NULL;
  704.  
  705.     disp_def.ModeID &= ~MONITOR_ID_MASK;
  706.  
  707.     if ( !ret && !(ret = OpenDisplay( &disp_def, ilbmfile ) ) ) {
  708.  
  709.     ret = PlayMPEG( track, flags );
  710.  
  711.     CloseDisplay( &disp_def );
  712.     }
  713.  
  714. exit:
  715.     MPEGDeviceTerm();
  716.     CDDeviceTerm();
  717.  
  718.     FreeArgs( rdargs );
  719.  
  720.     if ( !ret ) {
  721.     ret = RETURN_OK;
  722.     } else {
  723.     printf("'%ls'\n",ErrorMsg[ret]);
  724.     ret = RETURN_FAIL;
  725.     }
  726.  
  727.     closedown();
  728.  
  729.     exit( ret );
  730.  
  731. } // main()
  732.