home *** CD-ROM | disk | FTP | other *** search
- /*******************
- cdmpeg.c
-
- W.D.L 931014
- ********************/
-
- /*
- * COPYRIGHT: Unless otherwise noted, all files are Copyright (c) 1993-1999
- * Amiga, Inc. All rights reserved.
- *
- * DISCLAIMER: This software is provided "as is". No representations or
- * warranties are made with respect to the accuracy, reliability, performance,
- * currentness, or operation of this software, and all use is at your own risk.
- * Neither Amiga nor the authors assume any responsibility or liability
- * whatsoever with respect to your use of this software.
- */
-
- // Tab size is 8!
-
- #include <exec/types.h>
- #include <exec/memory.h>
-
- #include <graphics/gfxbase.h>
-
- #include <dos/dos.h>
- #include <intuition/intuition.h>
-
- #include <libraries/lowlevel.h>
-
- #include "devices/cd.h"
- #include <devices/mpeg.h>
-
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/mpeg_protos.h>
- #include <clib/lowlevel_protos.h>
-
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/graphics_pragmas.h>
- #include <pragmas/realtime_pragmas.h>
- #include <pragmas/mpeg_pragmas.h>
- #include <pragmas/lowlevel_pragmas.h>
-
-
- #include "stdio.h"
- #include <stdlib.h>
- #include <math.h> // For min() & max()
- #include <string.h> // for setmem()
-
- #include "disp_def.h"
- #include "retcodes.h"
- #include "cdmpeg.h"
-
- #include "cdmpeg_rev.h"
-
-
- #include "debugsoff.h"
- #define KPRINTF
- //#include "debugson.h"
-
-
- // argument parsing
- #define TEMPLATE "TRACK/A/N,BACK/K,LMBABORT/S,RMBABORT/S,FIREABORT/S,LACE/S,INFO/S" VERSTAG " Wayne D. Lutz"
- #define OPT_TRACK 0
- #define OPT_BACK 1
- #define OPT_LMBABORT 2
- #define OPT_RMBABORT 3
- #define OPT_FIREABORT 4
- #define OPT_LACE 5
- #define OPT_INFO 6
- #define OPT_COUNT 7
-
-
- LONG opts[OPT_COUNT];
- struct RDArgs * rdargs;
-
- BOOL DisplayIsPal;
-
-
- int CXBRK(void) { return(0); } /* Disable SASC CTRL/C handling */
- int chkabort(void) { return(0); } /* Indeed */
-
- // Error messages.
- STATIC UBYTE * ErrorMsg[] = {
- "No error",
- "Error while reading file",
- "Couldn't open file",
- "Not enough memory for operation",
- "Could not open cd/cdtv device",
- "Could not open window",
- "Could not open screen",
- "BAD MPEG Track specification.\nTry the INFO command line argument to see track info.",
- "Operation failed"
- };
-
-
- struct Library * IntuitionBase;
- struct Library * GfxBase;
- struct Library * IFFParseBase;
- struct Library * FreeAnimBase;
- struct Library * LowLevelBase;
-
- STATIC struct Device * MPEGDevice;
- STATIC struct MsgPort * MPEGPort;
- STATIC struct IOMPEGReq * MPEGReq;
-
- STATIC struct Device * CDDevice;
- STATIC struct MsgPort * CDPort;
- STATIC struct IOStdReq * CDDeviceMReq;
-
- IMPORT ULONG CopSignal;
-
- /*
- * Close every thing down.
- */
- STATIC VOID
- closedown( VOID )
- {
- if ( IntuitionBase )
- CloseLibrary( IntuitionBase );
-
- if ( GfxBase )
- CloseLibrary( GfxBase );
-
- if ( IFFParseBase )
- CloseLibrary( IFFParseBase );
-
- if ( FreeAnimBase )
- CloseLibrary( FreeAnimBase );
-
- if ( LowLevelBase )
- CloseLibrary( LowLevelBase );
-
- } // closedown()
-
-
- /*
- * Open all of the required libraries.
- */
- STATIC
- init( BOOL iff )
- {
- if ( !(IntuitionBase = OpenLibrary("intuition.library", 39L)) ) {
- printf("Could NOT open intuition.library V39!\n");
- return( RC_FAILED );
- }
-
- if(!(GfxBase = OpenLibrary("graphics.library",39L)) ) {
- printf("Could NOT open graphics.library V39!\n");
- return( RC_FAILED );
- }
-
- if(iff && !(IFFParseBase = OpenLibrary("iffparse.library",0L)) ) {
- printf("Could NOT open iffparse.library!\n");
- return( RC_FAILED );
- }
-
- D(PRINTF("init() IFFParseBase= 0x%lx\n",IFFParseBase);)
-
- if ( !(LowLevelBase = OpenLibrary( "lowlevel.library", 40L )) ) {
- printf("Could NOT open lowlevel.library!\n");
- return( RC_FAILED );
- }
-
- FreeAnimBase = OpenLibrary("freeanim.library",0L);
-
- return( RC_OK );
-
- } // init()
-
-
- VOID
- MPEGDeviceTerm( VOID )
- {
- if ( MPEGReq ) {
- if ( MPEGDevice ) {
- CloseDevice( (struct IORequest *)MPEGReq );
- MPEGDevice = NULL;
- }
-
- if ( MPEGPort ) {
- while( GetMsg( MPEGPort ) );
- }
-
- DeleteIORequest( MPEGReq );
- MPEGReq = NULL;
- }
-
- if ( MPEGPort ) {
- DeleteMsgPort( MPEGPort );
- MPEGPort = NULL;
- }
-
- } // MPEGDeviceTerm()
-
-
- /*
- * Attempts to open cd32mpeg.device if not already opened.
- * Returns:
- * retcode: (BOOL) reflects device's open state.
- * *opened: (BOOL) TRUE if opened by this call.
- */
- BOOL
- MPEGDeviceInit( ULONG * opened )
- {
-
- if ( opened )
- *opened = FALSE;
-
- if ( !MPEGDevice ) {
- D(PRINTF("MPEGDeviceInit() have to prep MPEGDevice!");)
-
- if ( MPEGPort = CreateMsgPort() ) {
- D(PRINTF("MPEGDeviceInit() GOT MPEGPort\n");)
-
- if ( MPEGReq = CreateIORequest( MPEGPort, sizeof (struct IOMPEGReq)) ) {
- D(PRINTF("MPEGDeviceInit() GOT MPEGDeviceMReq\n");)
-
- if ( !OpenDevice( MPEG_NAME, 0, (struct IORequest *)MPEGReq, 0 ) ) {
- D(PRINTF("MPEGDeviceInit() Got a Device\n");)
- MPEGDevice = MPEGReq->iomr_Req.io_Device;
- }
- }
- }
-
- if ( !MPEGDevice ) {
- D(PRINTF("MPEGDeviceInit() Failed!! port 0x%lx request 0x%lx device 0x%lx\n",
- MPEGPort, MPEGReq, MPEGDevice );)
-
- MPEGDeviceTerm();
- return( FALSE );
- }
-
- if ( opened )
- *opened = TRUE;
- }
-
- return( TRUE );
-
- } // MPEGDeviceInit()
-
-
- /*
- * Close cd.device if opened.
- */
- VOID
- CDDeviceTerm( VOID )
- {
- if ( CDDeviceMReq ) {
- if ( CDDevice ) {
-
- CloseDevice( (struct IORequest *)CDDeviceMReq );
- CDDevice = NULL;
- }
-
- if ( MPEGPort ) {
- while( GetMsg( MPEGPort ) );
- }
-
- DeleteStdIO( CDDeviceMReq );
- CDDeviceMReq = NULL;
- }
-
- if ( CDPort ) {
- DeleteMsgPort( CDPort );
- CDPort = NULL;
- }
-
- } // CDDeviceTerm()
-
-
- /*
- * Attempts to open cd.device if not already opened.
- * Returns:
- * retcode: (BOOL) reflects device's open state.
- * *opened: (BOOL) TRUE if opened by this call.
- */
- BOOL
- CDDeviceInit( ULONG * opened )
- {
- if ( opened )
- *opened = FALSE;
-
- if ( !CDDevice ) {
- D(PRINTF("CDDeviceInit() have to prep CDDevice!");)
-
- if ( CDPort = CreateMsgPort() ) {
- D(PRINTF("CDDeviceInit() GOT CDPort\n");)
- if ( CDDeviceMReq = CreateStdIO( CDPort ) ) {
- D(PRINTF("CDDeviceInit() GOT CDDeviceMReq\n");)
- // Try to open cd.device. If can't, try for cdtv.device.
-
- if ( !OpenDevice( CD_NAME, 0, (struct IORequest *)CDDeviceMReq, 0 ) ) {
- D(PRINTF("CDDeviceInit() Got a Device\n");)
- CDDevice = CDDeviceMReq->io_Device;
- }
- }
- }
-
- if ( !CDDevice ) {
- D(PRINTF("CDDeviceInit() Failed!! port 0x%lx request 0x%lx device 0x%lx\n",
- CDPort, CDDeviceMReq, CDDevice );)
-
- CDDeviceTerm();
- return( FALSE );
- }
-
- if ( opened )
- *opened = TRUE;
- }
-
- return( TRUE );
-
- } // CDDeviceInit()
-
-
- /*
- * SendIOR -- asynchronously execute a device command
- */
- BOOL
- SendIOR( struct IOStdReq * req, LONG cmd, ULONG off, ULONG len, APTR data)
- {
- req->io_Command = cmd;
- req->io_Offset = off;
- req->io_Length = len;
- req->io_Data = data;
-
- SendIO( (struct IORequest *)req);
-
- if ( req->io_Error ) {
- printf("SendIOR() ERROR!!! io_Error= %ld\n",req->io_Error);
- kprintf("SendIOR() ERROR!!! io_Error= %ld\n",req->io_Error);
- return( FALSE );
- } else {
- return( TRUE );
- }
-
- } // SendIOR()
-
-
- VOID
- DoBorder()
- {
- struct IOMPEGReq req = *MPEGReq; // structure copy
- struct MPEGBorderParams bp;
-
- if (req.iomr_Req.io_Device)
- {
- bp.mbp_BorderLeft = 0;
- bp.mbp_BorderTop = 0;
- bp.mbp_BorderRed = 17;
- bp.mbp_BorderGreen = 17;
- bp.mbp_BorderBlue = 17;
-
- req.iomr_Req.io_Command = MPEGCMD_SETBORDER;
- req.iomr_Req.io_Data = &bp;
- req.iomr_Req.io_Length = sizeof(bp);
- req.iomr_Req.io_Offset = 0;
- DoIO((struct IORequest *)&req);
- }
- }
-
-
- VOID
- DoSearch( int direction )
- {
- struct IOMPEGReq req = *MPEGReq; // structure copy
-
- req.iomr_Arg1 = 1 * direction;
- req.iomr_Arg2 = NULL;
-
- D(PRINTF("DoSearch direction= %ld\n",direction);)
-
- // SendIOR( (struct IOStdReq *)&req, MPEGCMD_SCAN, NULL, NULL, NULL );
-
- if ( SendIOR( (struct IOStdReq *)&req, MPEGCMD_SINGLESTEP, NULL, NULL, NULL ) )
- WaitIO( (struct IORequest *)&req );
-
- D(PRINTF("DoSearch END\n\n");)
-
- } // DoSearch()
-
-
- VOID
- DoPause( VOID )
- {
- STATIC BOOL Paused = FALSE;
- struct IOMPEGReq req = *MPEGReq; // structure copy
-
- Paused = !Paused;
-
- req.iomr_Arg1 = Paused;
- req.iomr_Arg2 = NULL;
-
- if ( SendIOR( (struct IOStdReq *)&req, MPEGCMD_PAUSE, NULL, NULL, NULL ) )
- WaitIO( (struct IORequest *)&req );
-
- } // DoPause()
-
- #define S(MASK) (MASK & state )
-
- BOOL
- ReadPort( ULONG flags )
- {
- STATIC ULONG oldstate = 0;
- ULONG state;
-
- if ( flags & (MPEG_LMBABORT|MPEG_RMBABORT) )
- state = ReadJoyPort( 0 );
-
- if ( flags & MPEG_LMBABORT ) {
- if ( (JP_TYPE_MASK & state) == JP_TYPE_MOUSE) {
- if (S(JPF_BTN2))
- return( TRUE );
- }
- }
-
- if ( flags & MPEG_RMBABORT ) {
- if ( (JP_TYPE_MASK & state) == JP_TYPE_MOUSE) {
- if (S(JPF_BTN1))
- return( TRUE );
- }
- }
-
- #ifdef OUTT // [
- if ( flags & MPEG_FIREABORT ) {
- state = ReadJoyPort( 1 );
-
- if ( ((JP_TYPE_MASK & state) == JP_TYPE_GAMECTLR) || ((JP_TYPE_MASK & state) == JP_TYPE_JOYSTK) ) {
- if (S(JPF_BTN2))
- return( TRUE );
- }
- }
- #else // ][
-
- state = ReadJoyPort( 1 );
-
- if ( flags & MPEG_FIREABORT ) {
- if ( ((JP_TYPE_MASK & state) == JP_TYPE_GAMECTLR) || ((JP_TYPE_MASK & state) == JP_TYPE_JOYSTK) ) {
- if (S(JPF_BTN2))
- return( TRUE );
- }
- }
-
- if ( S(JPF_BUTTON_PLAY) && (state != oldstate) )
- DoPause();
- /*
- if ( S(JPF_BUTTON_FORWARD) ) {
- DoSearch( 1 );
- } else if ( S(JPF_BUTTON_REVERSE) ) {
- DoSearch( -1 );
- }
- */
- #endif // ]
-
- oldstate = state;
-
- return( FALSE );
-
- } // ReadPort()
-
-
- VOID
- DumpTOC( union CDTOC * toc, int len )
- {
- int i;
-
- printf("FirstTrack= %ld, LastTrack= %ld, LeadOut LSN= %ld\n",
- toc[0].Summary.FirstTrack,toc[0].Summary.LastTrack,
- toc[0].Summary.LeadOut.LSN);
-
- len = MIN (len,(toc[0].Summary.LastTrack+1));
-
- for ( i = toc[0].Summary.FirstTrack; i < len; i++ ) {
- printf("%ld: Track #%ld, Position LSN= %ld, CtlAdr= %ld\n",
- i,toc[i].Entry.Track,toc[i].Entry.Position.LSN,
- toc[i].Entry.CtlAdr);
- }
-
- } // DumpTOC()
-
-
- PlayMPEG( ULONG track, ULONG flags )
- {
- union CDTOC * toc;
- struct MPEGVideoParamsSet mvp;
- ULONG signalMask,mpegsig,signals;
- int len,ret;
- BOOL done;
-
- len = 100;
-
- if ( !(toc = AllocVec ((len+1) * sizeof (union CDTOC), MEMF_CLEAR)) )
- return( RC_NO_MEM );
-
- ret = SendIOR( CDDeviceMReq, CD_TOCLSN, NULL, len, toc );
-
- if ( !ret ) {
- ret = RC_FAILED;
- printf("Could NOT get TOC!\n");
- goto exit;
- }
- WaitIO( (struct IORequest *)CDDeviceMReq );
-
- if ( flags & MPEG_INFO )
- DumpTOC( toc, len );
-
- if ( (track < toc[0].Summary.FirstTrack) || (track > toc[0].Summary.LastTrack) ) {
- ret = RC_BAD_TRACK;
- goto exit;
- }
- toc[toc[0].Summary.LastTrack + 1].Entry.Position.LSN = toc[0].Summary.LeadOut.LSN;
-
- MPEGReq->iomr_StreamType = MPEGSTREAM_SYSTEM;
- mvp.mvp_Fade = 65535; // Fade level. 0 = no MPEG video at all, 65535 = full saturation
- mvp.mvp_DisplayType = 0; // DisplayIsPal ? 3 : 4; // 3 = PAL (50Hz), 4 = NTSC (60Hz)
-
- ret = SendIOR( (struct IOStdReq *)MPEGReq, MPEGCMD_SETVIDEOPARAMS, NULL,
- sizeof (struct MPEGVideoParamsSet), &mvp );
-
- if ( !ret ) {
- ret = RC_FAILED;
- printf("Could NOT SETVIDEOPARAMS!\n");
- printf("iomr_MPEGError= %ld\n",MPEGReq->iomr_MPEGError);
- goto exit;
- }
- WaitIO( (struct IORequest *)MPEGReq );
-
- /* Set MPEG border position and color */
- DoBorder();
-
- MPEGReq->iomr_MPEGFlags = 0;
- MPEGReq->iomr_StreamType = MPEGSTREAM_SYSTEM;
- MPEGReq->iomr_SectorSize = 2328;
- MPEGReq->iomr_StreamStart = toc[track].Entry.Position.LSN;
-
- ret = SendIOR( (struct IOStdReq *)MPEGReq, MPEGCMD_PLAYLSN,
- toc[track].Entry.Position.LSN,
- toc[track + 1].Entry.Position.LSN - toc[track].Entry.Position.LSN,
- NULL );
-
- if ( !ret ) {
- ret = RC_FAILED;
- printf("Could NOT PLAYLSN!\n");
- printf("iomr_MPEGError= %ld\n",MPEGReq->iomr_MPEGError);
- goto exit;
- }
- ret = RC_OK;
-
- mpegsig = 1L << MPEGPort->mp_SigBit;
-
- signalMask = SIGBREAKF_CTRL_C | mpegsig | CopSignal;
-
- done = FALSE;
- while ( !done ) {
-
- signals = Wait( signalMask );
-
- if ( GetMsg( MPEGPort ) ) {
- D(PRINTF("Got Msg from MPEGPort\n");)
- done = TRUE;
- }
-
- if ( signals & SIGBREAKF_CTRL_C ) {
- D(PRINTF("GOT a CTRL_C\n");)
- if ( !CheckIO( (struct IORequest *)MPEGReq ) ) {
- D(PRINTF("Aborting!!\n");)
- AbortIO( (struct IORequest *)MPEGReq );
- WaitIO( (struct IORequest *)MPEGReq );
- }
- done = TRUE;
- }
-
- if ( signals & CopSignal ) {
- if ( flags & MPEG_BUTTONABORTMASK ) {
- if ( ReadPort( flags ) ) {
- D(PRINTF("Button Aborting!!\n");)
- if ( !CheckIO( (struct IORequest *)MPEGReq ) ) {
- D(PRINTF("Aborting!!\n");)
- AbortIO( (struct IORequest *)MPEGReq );
- WaitIO( (struct IORequest *)MPEGReq );
- }
- done = TRUE;
- }
- }
- }
-
- }
-
- if ( SendIOR( (struct IOStdReq *)MPEGReq, CMD_FLUSH, NULL, NULL, NULL ) ) {
- WaitIO( (struct IORequest *)MPEGReq );
- }
-
- exit:
-
- FreeVec( toc );
-
- return( ret );
-
- } // PlayMPEG()
-
-
- VOID
- main( LONG argc,char * argv[] )
- {
- UBYTE * ilbmfile;
- ULONG track,flags = NULL;
- struct DisplayInfo disp;
- int ret;
- DISP_DEF disp_def ;
-
- // workbench
- if ( argc == 0 )
- exit( RETURN_ERROR );
-
- setmem( opts, sizeof (opts) ,0 );
-
- rdargs = ReadArgs(TEMPLATE, opts, NULL);
-
- if ( !rdargs ) {
- PrintFault(IoErr(), NULL);
- exit( RETURN_ERROR );
- }
-
- ilbmfile = (UBYTE *)opts[OPT_BACK];
- track = *(ULONG *)opts[OPT_TRACK];
-
- if ( ret = init( ilbmfile ? TRUE : FALSE ) ) {
- closedown();
- exit( RETURN_FAIL );
- }
-
- setmem( &disp_def, sizeof (DISP_DEF) ,0 );
-
- disp_def.Flags |= DISP_SCREEN|DISP_NOPOINTER|DISP_COP_INT;
-
- if ( ilbmfile ) {
- disp_def.Flags |= (DISP_INTERLEAVED|DISP_BACKGROUND|DISP_ALLOCBM);
-
- // Query the ILBM to find what sort of display to open.
- if ( !DoQuery( ilbmfile, &disp_def ) ) {
- ret = RC_CANT_FIND;
- PF("main RC_CANT_FIND");
- closedown();
- exit( RETURN_FAIL );
- }
-
- } else {
- disp_def.Width = 320;
- disp_def.Depth = 1;
-
- if ( opts[OPT_LACE] ) {
- disp_def.Height = 400;
- disp_def.ModeID = LORESLACE_KEY;
- } else {
- disp_def.Height = 200;
- disp_def.ModeID = LORES_KEY;
- }
- }
-
- D(PRINTF("ilbmfile= '%ls'\n", PFSTR(ilbmfile) );)
-
- DisplayIsPal = FALSE;
- if ( GetDisplayInfoData(NULL, (UBYTE *)&disp, sizeof(struct DisplayInfo), DTAG_DISP, LORES_KEY) ) {
- if ( disp.PropertyFlags & DIPF_IS_PAL )
- DisplayIsPal = TRUE;
- }
-
- D(PRINTF("display type= '%ls', gfxbase says '%ls' - '%ls'\n",
- DisplayIsPal ? "PAL" : "NTSC",
- (GfxBase->DisplayFlags & PAL) ? "PAL" : "NTSC",
- (GfxBase->DisplayFlags & REALLY_PAL) ? "REALLY_PAL" : "REALLY_NTSC" );)
-
- D(PRINTF("After Query disp_def.Width= %ld, Height= %ld\n",
- disp_def.Width,disp_def.Height);)
-
- if ( opts[OPT_LMBABORT] )
- flags |= MPEG_LMBABORT;
-
- if ( opts[OPT_RMBABORT] )
- flags |= MPEG_RMBABORT;
-
- if ( opts[OPT_FIREABORT] )
- flags |= MPEG_FIREABORT;
-
- if ( opts[OPT_INFO] )
- flags |= MPEG_INFO;
-
- CDDeviceInit( NULL );
- MPEGDeviceInit( NULL );
-
- if ( !(CDDeviceMReq && MPEGReq) ) {
- // ret = RC_FAILED;
- ret = RC_OK; // So no error messages are printed to the console
- goto exit;
- }
-
- D(PRINTF("\nCDDeviceMReq= 0x%lx, MPEGReq= 0x%lx\n",
- CDDeviceMReq,MPEGReq);)
-
- CloseLibrary( FreeAnimBase );
- FreeAnimBase = NULL;
-
- disp_def.ModeID &= ~MONITOR_ID_MASK;
-
- if ( !ret && !(ret = OpenDisplay( &disp_def, ilbmfile ) ) ) {
-
- ret = PlayMPEG( track, flags );
-
- CloseDisplay( &disp_def );
- }
-
- exit:
- MPEGDeviceTerm();
- CDDeviceTerm();
-
- FreeArgs( rdargs );
-
- if ( !ret ) {
- ret = RETURN_OK;
- } else {
- printf("'%ls'\n",ErrorMsg[ret]);
- ret = RETURN_FAIL;
- }
-
- closedown();
-
- exit( ret );
-
- } // main()
-