home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / anim / players / mpeg_src.lha / amiga / amiga.c next >
C/C++ Source or Header  |  1993-02-13  |  20KB  |  1,024 lines

  1. /*
  2.  * Implementation of the needed X functions for the Commodore Amiga
  3.  *
  4.  * Michael Balzer, December 1992
  5.  * balzer@heike.informatik.uni-dortmund.de
  6.  * bilbo@bagsend.aworld.de
  7.  * m.balzer@aworld.(aworld.de|zer|sub.org)
  8.  *
  9.  * Release 1.0 (8.12.92):
  10.  *        - First release, needs os3.0, can only display on
  11.  *          workbench or on 8 bit lores screen
  12.  *
  13.  * Release 1.22 (11.12.92):
  14.  *        - Now also runs on system 2.x
  15.  *        - Uses reqtools.library to ask for the screenmode
  16.  *        - Version string: 1.22 means Amiga version 2 of mpeg_play 1.2
  17.  *
  18.  * Release 1.23 (not released due to 2.01):
  19.  *        - Dither mono & threshold now work (fast!)
  20.  *        - New option: -saveiff framename_%d.iff (guess for what ;-)
  21.  *          Saving currently forces screen mode. No support for 24 bit
  22.  *          yet
  23.  *        - Added new option: -amiga screen:mode/depth/width/height,
  24.  *          reworked option dependancies
  25.  *
  26.  * Release 2.01 (Feb 12 1993):
  27.  *        - Based upon the new 2.0 release of the mpeg player for UNIX
  28.  *        - No need to enhance color allocation, as the new player
  29.  *          allows to set the range values (ncolors = l_rng*cr_rng*cb_rng)
  30.  *        - 24 Bit IFF save mode implemented
  31.  *
  32.  * TODO:
  33.  *        - maybe implement HAM mode
  34.  */
  35.  
  36.  
  37. #include <exec/types.h>
  38. #include <exec/memory.h>
  39. #include <exec/libraries.h>
  40. #include <intuition/intuition.h>
  41. #include <intuition/classes.h>
  42. #include <graphics/gfxbase.h>
  43. #include <graphics/gfxmacros.h>
  44. #include <graphics/modeid.h>
  45. #include <graphics/scale.h>
  46. #include <graphics/graphint.h>
  47. #include <dos/dos.h>
  48.  
  49. #include <clib/exec_protos.h>
  50. #include <clib/intuition_protos.h>
  51. #include <clib/graphics_protos.h>
  52. #include <clib/alib_protos.h>
  53.  
  54. #include <libraries/reqtools.h>
  55. #include <proto/reqtools.h>
  56. #define static
  57. #define __inline
  58. #include <inline/minreqtools.h>
  59. #undef static
  60. #undef __inline
  61.  
  62. #include <X11/Xlib.h>
  63. #include <X11/Xutil.h>
  64.  
  65. #include <iffp/ilbmapp.h>
  66.  
  67. #include <stdio.h>
  68. #include <stdlib.h>
  69.  
  70. #include "video.h"
  71.  
  72. #ifdef ABS
  73. #undef ABS
  74. #endif
  75. #define ABS(a) (((int)(a)<0) ? -(a) : (a))
  76.  
  77.  
  78. char *_version_ = "\0$VER: mpeg_play 2.01 (" __DATE__ ")";
  79.  
  80.  
  81. /***********************************************************/
  82.  
  83.  
  84. extern
  85. struct Library        *SysBase;
  86.  
  87.  
  88. struct IntuitionBase *IntuitionBase = NULL;
  89. struct GfxBase        *GfxBase = NULL;
  90. struct Library        *IFFParseBase = NULL;
  91. struct ReqToolsBase    *ReqToolsBase = NULL;
  92.  
  93. struct Screen        *mpeg_screen = NULL;
  94. struct Window        *mpeg_window = NULL;
  95. struct RastPort        *rp = NULL;
  96.  
  97. struct RastPort        *temprp = NULL;
  98. struct BitMap        *tempbm = NULL;
  99. struct BitMap        *bwbm = NULL;
  100. struct ViewPort        *vp = NULL;
  101.  
  102. char                *amiga_option = "";
  103.  
  104. int                    offx, offy;
  105.  
  106. struct ColorMap        *cm = NULL;
  107. int                    used_colors[ 256 ];
  108. int                    used_cnt = 0;
  109.  
  110. UWORD                saved_colors[ 256 ];
  111. int                    saved_cnt = 0;
  112.  
  113. int                    rev3;
  114.  
  115. char                *saveiff_option = "";
  116. int                    saveFlag = 0;
  117. extern int            loopFlag;
  118. struct ILBMInfo        *ilbm = 0;
  119.  
  120. extern int            ditherType;
  121.  
  122. unsigned char        *rsrc = 0, *gsrc = 0, *bsrc = 0;
  123. struct BitMap        *bm24 = 0, *rbm = 0, *gbm = 0, *bbm = 0;
  124. struct RastPort        *rrp = 0, *grp = 0, *brp = 0;
  125. struct RastPort        *rtemprp = 0, *gtemprp = 0, *btemprp = 0;
  126.  
  127. int                    real_width, real_height;
  128.  
  129.  
  130. /***********************************************************/
  131.  
  132. /* support routines for os revision 2 */
  133.  
  134. struct BitMap *myAllocBitMap( unsigned long sizex, unsigned long sizey,
  135.     unsigned long depth, unsigned long flags,
  136.     struct BitMap *friend_bitmap )
  137. {
  138.     struct BitMap *bm;
  139.     unsigned long extra;
  140.     
  141.     extra = (depth > 8) ? depth - 8 : 0;
  142.     bm = AllocVec( sizeof *bm + (extra * 4), MEMF_CLEAR );
  143.     
  144.     if( bm )
  145.     {
  146.         int i;
  147.         
  148.         InitBitMap( bm, depth, sizex, sizey );
  149.         
  150.         for( i=0; i<depth; i++ )
  151.         {
  152.             if( !(bm->Planes[i] = AllocRaster(sizex, sizey)) )
  153.             {
  154.                 while( i-- ) FreeRaster( bm->Planes[i], sizex, sizey );
  155.                 FreeVec( bm );
  156.                 bm = 0;
  157.                 break;
  158.             }
  159.         }
  160.     }
  161.     
  162.     return bm;
  163. }
  164.  
  165.  
  166. void myFreeBitMap( struct BitMap *bm )
  167. {
  168.     while( bm->Depth-- )
  169.         FreeRaster( bm->Planes[bm->Depth], bm->BytesPerRow*8, bm->Rows );
  170.     FreeVec( bm );
  171. }
  172.  
  173.  
  174. LONG myObtainBestPenA( struct ColorMap *cm, unsigned long r, unsigned long g,
  175.     unsigned long b, struct TagItem *tags )
  176. {
  177.     int i, best, err, besterr;
  178.     int br, bg, bb;
  179.     int colors;
  180.     
  181.     /* Farbwerte auf 4 Bit bringen */
  182.     
  183.     r >>= 28; g >>= 28; b >>= 28;
  184.     
  185.     /* Strategie: Zunächst die Farbe suchen, die der gewünschten
  186.      * am nächsten liegt. Wenn Farbe >= 4, Farbe auf Mittelwert zw.
  187.      * aktuellen und gesuchten Werten setzen und zurückgeben.
  188.      * Die unteren vier bleiben unverändert (Workbench).
  189.      */
  190.     
  191.     best = 0;
  192.     besterr = 100;
  193.     
  194.     colors = 1 << rp->BitMap->Depth;
  195.     
  196.     for( i=0; i<colors; i++ )
  197.     {
  198.         long rgb = GetRGB4( cm, i );
  199.         int cr, cg, cb;
  200.         
  201.         cr = rgb >> 8 & 15;
  202.         cg = rgb >> 4 & 15;
  203.         cb = rgb      & 15;
  204.         
  205.         err = ABS( r - cr )
  206.             + ABS( g - cg )
  207.             + ABS( b - cb );
  208.         
  209.         if( err < besterr )
  210.         {
  211.             best = i;
  212.             besterr = err;
  213.             br = cr;
  214.             bg = cg;
  215.             bb = cb;
  216.         }
  217.     }
  218.     
  219.     if( best >= 4 && besterr != 0 )
  220.     {
  221.         /* Farbe anpassen */
  222.         SetRGB4( vp, best,
  223.             (r + br) / 2,
  224.             (g + bg) / 2,
  225.             (b + bb) / 2 );
  226.     }
  227.     
  228.     return best;
  229. }
  230.  
  231.  
  232. void myReleasePen( struct ColorMap *cm, unsigned long n )
  233. {
  234.     /* Farbe restaurieren */
  235.     long rgb = saved_colors[n];
  236.     int cr, cg, cb;
  237.     
  238.     cr = rgb >> 8 & 15;
  239.     cg = rgb >> 4 & 15;
  240.     cb = rgb      & 15;
  241.     
  242.     SetRGB4( vp, n, cr, cg, cb );
  243. }
  244.  
  245.  
  246. /***********************************************************/
  247.  
  248.  
  249. void FreeTempRP( struct RastPort *rp )
  250. {
  251.     if( rp )
  252.     {
  253.         if( rp->BitMap )
  254.         {
  255.             if( rev3 ) FreeBitMap( rp->BitMap );
  256.             else myFreeBitMap( rp->BitMap );
  257.         }
  258.         
  259.         FreeVec( rp );
  260.     }
  261. }
  262.  
  263.  
  264. struct RastPort *MakeTempRP( struct RastPort *org )
  265. {
  266.     struct RastPort *rp;
  267.     
  268.     if( rp = AllocVec(sizeof *rp, MEMF_ANY) )
  269.     {
  270.         memcpy( rp, org, sizeof *rp );
  271.         rp->Layer = NULL;
  272.         
  273.         if( rev3 )
  274.             rp->BitMap = AllocBitMap( org->BitMap->BytesPerRow * 8, 1,
  275.                 org->BitMap->Depth, NULL, org->BitMap );
  276.         else
  277.             rp->BitMap = myAllocBitMap( org->BitMap->BytesPerRow * 8, 1,
  278.                 org->BitMap->Depth, NULL, org->BitMap );
  279.         
  280.         if( !rp->BitMap )
  281.         {
  282.             FreeVec( rp );
  283.             rp = NULL;
  284.         }
  285.     }
  286.     
  287.     return rp;
  288. }
  289.  
  290.  
  291. void amiga_closedown( void )
  292. {
  293.     if( cm )
  294.     {
  295.         while( used_cnt-- )
  296.             if( rev3 ) ReleasePen( cm, used_colors[used_cnt] );
  297.             else myReleasePen( cm, used_colors[used_cnt] );
  298.     }
  299.     
  300.     if( mpeg_window ) CloseWindow( mpeg_window );
  301.     
  302.     if( mpeg_screen ) CloseScreen( mpeg_screen );
  303.     
  304.     FreeTempRP( temprp );
  305.     
  306.     if( bwbm )
  307.     {
  308.         if( rev3 ) FreeBitMap( bwbm );
  309.         else myFreeBitMap( bwbm );
  310.     }
  311.  
  312.     if( ilbm )
  313.     {
  314.         if( ilbm->ParseInfo.iff )
  315.             FreeIFF( ilbm->ParseInfo.iff );
  316.         FreeVec( ilbm );
  317.     }
  318.     
  319.     if( rsrc ) FreeVec( rsrc );
  320.     if( gsrc ) FreeVec( gsrc );
  321.     if( bsrc ) FreeVec( bsrc );
  322.     
  323.     if( bm24 ) myFreeBitMap( bm24 );
  324.     
  325.     if( rbm ) { rbm->Depth = 0; myFreeBitMap( rbm ); }
  326.     if( gbm ) { gbm->Depth = 0; myFreeBitMap( gbm ); }
  327.     if( bbm ) { bbm->Depth = 0; myFreeBitMap( bbm ); }
  328.     
  329.     if( rrp ) FreeVec( rrp );
  330.     if( grp ) FreeVec( grp );
  331.     if( brp ) FreeVec( brp );
  332.     
  333.     FreeTempRP( rtemprp );
  334.     FreeTempRP( gtemprp );
  335.     FreeTempRP( btemprp );
  336.     
  337.     if( ReqToolsBase )    CloseLibrary( (struct Library *) ReqToolsBase );
  338.     if( IFFParseBase )    CloseLibrary( (struct Library *) IFFParseBase );
  339.     if( GfxBase )        CloseLibrary( (struct Library *) GfxBase );
  340.     if( IntuitionBase )    CloseLibrary( (struct Library *) IntuitionBase );
  341. }
  342.  
  343.  
  344. void open_display( void )
  345. {
  346.     struct rtScreenModeRequester *scrmodereq;
  347.     
  348.     static struct TagItem windowtags[] =
  349.     {
  350.         {    WA_PubScreen,    NULL },
  351.         {    WA_Left,        32 },
  352.         {    WA_Top,            32 },
  353.         {    WA_Width,        160 },
  354.         {    WA_Height,        120 },
  355.         {    WA_Title,        (ULONG) "MPEG Window" },
  356.         {    WA_IDCMP,        IDCMP_CLOSEWINDOW },
  357.         {    WA_Flags,        WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_NOCAREREFRESH | WFLG_ACTIVATE | WFLG_RMBTRAP },
  358.         {    WA_ScreenTitle,    (ULONG) "MPEG Player V2.01, Amiga version by Michael Balzer 2/93" },
  359.         {    TAG_END }
  360.     };
  361.  
  362.  
  363.     if( strcmp(amiga_option, "window") == 0 )
  364.     {
  365.         /* try to open a window */
  366.         struct Screen *s;
  367.         
  368.         if( s = LockPubScreen(NULL) )
  369.         {
  370.             windowtags[0].ti_Data = (ULONG) s;
  371.             mpeg_window = OpenWindowTagList( NULL, windowtags );
  372.             if( mpeg_window )
  373.             {
  374.                 rp = mpeg_window->RPort;
  375.                 offx = mpeg_window->BorderLeft;
  376.                 offy = mpeg_window->BorderTop;
  377.             }
  378.             
  379.             UnlockPubScreen( NULL, s );
  380.         }
  381.     }
  382.     
  383.     /* fallback to own screen */
  384.     
  385.     if( !mpeg_window )
  386.     {
  387.         BOOL ok;
  388.         ULONG id=0, width=320, height=200, depth=8, oscan=0;
  389.         
  390.         if( strncmp(amiga_option, "screen", 6) == 0 )
  391.         {
  392.             char *s = strtok( amiga_option, ":/" );
  393.             int i;
  394.             
  395.             for( i=0; s; s=strtok(NULL, ":/") )
  396.             {
  397.                 switch( i++ )
  398.                 {
  399.                     case 0:
  400.                         /* discard first one */
  401.                         break;
  402.                     case 1:
  403.                         if( *s )
  404.                             id = strtol( s, NULL, 0 );
  405.                         break;
  406.                     case 2:
  407.                         if( *s )
  408.                             depth = atoi( s );
  409.                         break;
  410.                     case 3:
  411.                         if( *s )
  412.                             width = atol( s );
  413.                         break;
  414.                     case 4:
  415.                         if( *s )
  416.                             height = atol( s );
  417.                         break;
  418.                 }
  419.             }
  420.             
  421.             ok = TRUE;
  422.         }
  423.         else
  424.         {
  425.             if( scrmodereq = rtAllocRequestA( RT_SCREENMODEREQ, NULL ) )
  426.             {
  427.                 ok = rtScreenModeRequest( scrmodereq,
  428.                     "MPEG: Pick a screen mode",
  429.                     RTSC_Flags, SCREQF_DEPTHGAD|SCREQF_SIZEGADS|SCREQF_OVERSCANGAD,
  430.                     TAG_END );
  431.                 
  432.                 rtFreeRequest( scrmodereq );
  433.                 
  434.                 id     = scrmodereq->DisplayID;
  435.                 width  = scrmodereq->DisplayWidth;
  436.                 height = scrmodereq->DisplayHeight;
  437.                 depth  = scrmodereq->DisplayDepth;
  438.                 oscan  = scrmodereq->OverscanType;
  439.                 
  440.                 if( ok )
  441.                     printf( "  -amiga screen:0x%lx/%d/%d/%d\n",
  442.                         id, depth, width, height );
  443.             }
  444.             else
  445.                 ok = FALSE;
  446.         }
  447.         
  448.         if( ok )
  449.         {
  450.             mpeg_screen = OpenScreenTags( NULL,
  451.                 SA_Title,        (ULONG) "MPEG Screen",
  452.                 SA_DisplayID,    id,
  453.                 SA_Width,        width,
  454.                 SA_Height,        height,
  455.                 SA_Depth,        depth,
  456.                 SA_Overscan,    oscan,
  457.                 SA_Quiet,        TRUE,
  458.                 SA_SharePens,    TRUE,
  459.                 TAG_END );
  460.             
  461.             /* SA_AutoScroll,    scrmodereq->AutoScroll, */
  462.             /* Autoscroll would need a backdrop window, but that
  463.              * would posssibly slow it down even more...
  464.              */
  465.         }
  466.         
  467.         if( mpeg_screen )
  468.             rp = &mpeg_screen->RastPort;
  469.         offx = offy = 0;
  470.     }
  471. }
  472.  
  473.  
  474. Display *XOpenDisplay( _Xconst char *display_name )
  475. {
  476.     int y;
  477.     
  478.     if( !IntuitionBase )
  479.     {
  480.         /* install closedown routine */
  481.         
  482.         atexit( amiga_closedown );
  483.         
  484.         /* open shared libraries */
  485.         
  486.         IntuitionBase = (struct IntuitionBase *) OpenLibrary( "intuition.library", 0 );
  487.         if( !IntuitionBase ) return NULL;
  488.         
  489.         GfxBase = (struct GfxBase *) OpenLibrary( "graphics.library", 0 );
  490.         if( !GfxBase ) return NULL;
  491.         
  492.         IFFParseBase = OpenLibrary( "iffparse.library", 0 );
  493.         if( !IFFParseBase ) return NULL;
  494.         
  495.         ReqToolsBase = (struct ReqToolsBase *) OpenLibrary( "reqtools.library", 38 );
  496.         if( !ReqToolsBase )
  497.         {
  498.             puts( "I need reqtools.library v38!\n" );
  499.             return NULL;
  500.         }
  501.         
  502.         rev3 = (GfxBase->LibNode.lib_Version >= 39);
  503.     }
  504.     
  505.     /* Save option enabled? */
  506.     
  507.     if( *saveiff_option )
  508.     {
  509.         saveFlag = 1;
  510.         loopFlag = 0;        /* don't loop while saving */
  511.         
  512.         if( !(ilbm = (struct ILBMInfo *) AllocVec( sizeof *ilbm, MEMF_CLEAR )) )
  513.         {
  514.             puts( "out of mem" );
  515.             return NULL;
  516.         }
  517.         
  518.         if( !(ilbm->ParseInfo.iff = AllocIFF()) )
  519.         {
  520.             puts( "no iff handle" );
  521.             return NULL;
  522.         }
  523.         
  524.         /* iffp routines need screen for saving */
  525.         if( strcmp( amiga_option, "window" ) == 0 )
  526.             amiga_option = "";
  527.     }
  528.         
  529.     if( ditherType == FULL_COLOR_DITHER )
  530.     {
  531.         if( !saveFlag )
  532.             return (Display *) 0;
  533.     }
  534.     else
  535.     {
  536.         /* open some display */
  537.  
  538.         open_display();
  539.         
  540.         if( !mpeg_window && !mpeg_screen )
  541.             return NULL;
  542.         
  543.         /* Viewport und Colormap bestimmen */
  544.         
  545.         vp = (mpeg_screen)
  546.             ? &mpeg_screen->ViewPort
  547.             : &mpeg_window->WScreen->ViewPort;
  548.  
  549.         cm = vp -> ColorMap;
  550.  
  551.         /* Farben sichern */
  552.         
  553.         saved_cnt = 1 << rp->BitMap->Depth;
  554.         for( y=0; y<saved_cnt; y++ )
  555.             saved_colors[y] = GetRGB4( cm, y );
  556.         
  557.         /* temporären Rastport aufsetzen */
  558.         
  559.         temprp = MakeTempRP( rp );
  560.         if( !temprp )
  561.         {
  562.             puts( "out of memory!" );
  563.             exit( 20 );
  564.         }
  565.     }
  566.     
  567.     return (Display *) 1;
  568. }
  569.  
  570.  
  571. int XDefaultScreen( Display *display )
  572. {
  573.     return 1;
  574. }
  575.  
  576.  
  577. XFlush( Display *display )
  578. {
  579. }
  580.  
  581.  
  582. /***************************************************************/
  583.  
  584.  
  585. Window XRootWindow(
  586.     Display*        display,
  587.     int                screen_number )
  588. {
  589.     return 1;
  590. }
  591.  
  592.  
  593. Window XCreateSimpleWindow(
  594.     Display*        display,
  595.     Window            parent,
  596.     int                x,
  597.     int                y,
  598.     unsigned int    width,
  599.     unsigned int    height,
  600.     unsigned int    border_width,
  601.     unsigned long    border,
  602.     unsigned long    background )
  603. {
  604.     return (Window) 1;
  605. }
  606.  
  607.  
  608. Window XCreateWindow(
  609.     Display*        display,
  610.     Window            parent,
  611.     int                x,
  612.     int                y,
  613.     unsigned int    width,
  614.     unsigned int    height,
  615.     unsigned int    border_width,
  616.     int                depth,
  617.     unsigned int    class,
  618.     Visual*            visual,
  619.     unsigned long    valuemask,
  620.     XSetWindowAttributes*    attributes )
  621. {
  622.     /* Generiert Fenster auf Full-Color-Display */
  623.     
  624.     /* für's Frame-Speichern sinnvoll,
  625.      * dafür wird aber kein echter Output gemacht,
  626.      * sondern nur direkt gespeichert.
  627.      */
  628.  
  629.     return (Window) 1;
  630. }
  631.  
  632.  
  633. XSetStandardProperties(
  634.     Display*        display,
  635.     Window            w,
  636.     _Xconst char*    window_name,
  637.     _Xconst char*    icon_name,
  638.     Pixmap            icon_pixmap,
  639.     char**            argv,
  640.     int                argc,
  641.     XSizeHints*        hints )
  642. {
  643. }
  644.  
  645.  
  646. XMapWindow(
  647.     Display*        display,
  648.     Window            w )
  649. {
  650. }
  651.  
  652.  
  653. XResizeWindow(
  654.     Display*        display,
  655.     Window            w,
  656.     unsigned int    width,
  657.     unsigned int    height )
  658. {
  659.     printf( "Anim size: %d x %d\n", width, height );
  660.     
  661.     /* für später... */
  662.     real_width  = width;
  663.     real_height = height;
  664.     
  665.     if( mpeg_screen ) return;
  666.     
  667.     if( mpeg_window )
  668.         ChangeWindowBox( mpeg_window,
  669.             mpeg_window->LeftEdge, mpeg_window->TopEdge,
  670.             width + mpeg_window->BorderLeft + mpeg_window->BorderRight,
  671.             height + mpeg_window->BorderTop + mpeg_window->BorderBottom );
  672. }
  673.  
  674.  
  675. /***************************************************************/
  676.  
  677.  
  678. Status XMatchVisualInfo(
  679.     Display*        display,
  680.     int                screen,
  681.     int                depth,
  682.     int                class,
  683.     XVisualInfo*    vinfo_return )
  684. {
  685.     return( depth <= 8 );
  686. }
  687.  
  688.  
  689. XVisualInfo *XGetVisualInfo(
  690.     Display*        display,
  691.     long            vinfo_mask,
  692.     XVisualInfo*    vinfo_template,
  693.     int*            nitems_return )
  694. {
  695.     *nitems_return = 0;
  696.     return vinfo_template;
  697. }
  698.  
  699.  
  700. GC XCreateGC(
  701.     Display*        display,
  702.     Drawable        d,
  703.     unsigned long    valuemask,
  704.     XGCValues*        values )
  705. {
  706.     return (GC) 1;
  707. }
  708.  
  709.  
  710. /***************************************************************/
  711.  
  712.  
  713. XImage *XCreateImage(
  714.     Display*        display,
  715.     Visual*            visual,
  716.     unsigned int    depth,
  717.     int                format,
  718.     int                offset,
  719.     char*            data,
  720.     unsigned int    width,
  721.     unsigned int    height,
  722.     int                bitmap_pad,
  723.     int                bytes_per_line )
  724. {
  725.     XImage *xi;
  726.     
  727.     /* Höhenkorrektur */
  728.     width  = real_width;
  729.     height = real_height;
  730.     
  731.     if( xi = calloc(sizeof *xi, 1) )
  732.     {
  733.         xi->width   = width;
  734.         xi->height  = height;
  735.         xi->depth   = depth;
  736.         
  737.         xi->f.destroy_image = (int (*)()) free;
  738.         
  739.         if( depth == 1 )
  740.         {
  741.             /* BitMap im ChipMem allokieren */
  742.             if( rev3 )
  743.                 bwbm = AllocBitMap( width, height, 1, NULL, rp->BitMap );
  744.             else
  745.                 bwbm = myAllocBitMap( width, height, 1, NULL, rp->BitMap );
  746.             
  747.             if( !bwbm )
  748.             {
  749.                 puts( "XCreateImage: Out of memory!" );
  750.                 exit( 20 );
  751.             }
  752.         }
  753.         else if( depth >= 24 )
  754.         {
  755.             /* Save-BitMap anlegen */
  756.             int i;
  757.             
  758.             /* R, G und B-Bereich für WPA8 */
  759.             rsrc = AllocVec( width * height, MEMF_ANY );
  760.             gsrc = AllocVec( width * height, MEMF_ANY );
  761.             bsrc = AllocVec( width * height, MEMF_ANY );
  762.             
  763.             if( !rsrc || !gsrc || !bsrc )
  764.             {
  765.                 puts( "XCreateImage: Out of memory!" );
  766.                 exit( 20 );
  767.             }
  768.             
  769.             /* 24-Bit-BitMap */
  770.             bm24 = myAllocBitMap( width, height, 24, NULL, NULL );
  771.             
  772.             if( !bm24 )
  773.             {
  774.                 puts( "XCreateImage: Out of memory!" );
  775.                 exit( 20 );
  776.             }
  777.             
  778.             /* 8-Bit-BitMaps */
  779.             rbm = myAllocBitMap( width, height, 0, NULL, NULL );
  780.             gbm = myAllocBitMap( width, height, 0, NULL, NULL );
  781.             bbm = myAllocBitMap( width, height, 0, NULL, NULL );
  782.             
  783.             if( !rbm || !gbm || !bbm )
  784.             {
  785.                 puts( "XCreateImage: Out of memory!" );
  786.                 exit( 20 );
  787.             }
  788.             
  789.             rbm->Depth = 8;
  790.             for( i=0; i<8; i++ ) rbm->Planes[i] = bm24->Planes[i];
  791.             gbm->Depth = 8;
  792.             for( i=0; i<8; i++ ) gbm->Planes[i] = bm24->Planes[8+i];
  793.             bbm->Depth = 8;
  794.             for( i=0; i<8; i++ ) bbm->Planes[i] = bm24->Planes[16+i];
  795.             
  796.             /* 8-Bit-RastPorts */
  797.             rrp = AllocVec( sizeof *rrp, MEMF_ANY );
  798.             grp = AllocVec( sizeof *grp, MEMF_ANY );
  799.             brp = AllocVec( sizeof *brp, MEMF_ANY );
  800.             
  801.             if( !rrp || !grp || !brp )
  802.             {
  803.                 puts( "XCreateImage: Out of memory!" );
  804.                 exit( 20 );
  805.             }
  806.             
  807.             InitRastPort( rrp );
  808.             InitRastPort( grp );
  809.             InitRastPort( brp );
  810.             
  811.             rrp->BitMap = rbm;
  812.             grp->BitMap = gbm;
  813.             brp->BitMap = bbm;
  814.             
  815.             rtemprp = MakeTempRP( rrp );
  816.             gtemprp = MakeTempRP( grp );
  817.             btemprp = MakeTempRP( brp );
  818.             
  819.             if( !rtemprp || !gtemprp || !btemprp )
  820.             {
  821.                 puts( "XCreateImage: Out of memory!" );
  822.                 exit( 20 );
  823.             }
  824.         }
  825.     }
  826.     
  827.     return xi;
  828. }
  829.  
  830.  
  831. XPutImage(
  832.     Display*        display,
  833.     Drawable        d,
  834.     GC                gc,
  835.     XImage*            image,
  836.     int                src_x,
  837.     int                src_y,
  838.     int                dest_x,
  839.     int                dest_y,
  840.     unsigned int    width,
  841.     unsigned int    height       )
  842. {
  843.     struct IntuiMessage    *imsg;
  844.     ULONG                class;
  845.  
  846.     /* in image->data ist das Bild als Folge von Bytes,
  847.      * display zeigt auf nix,
  848.      * d und gc sind egal,
  849.      * src_? und dest_? sind hier immer 0,
  850.      * width und height stimmen mit den Bilddimensionen überein
  851.      * (oder sollten zumindest...)
  852.      */
  853.     
  854.     if( image->depth == 1 )
  855.     {
  856.         /* B&W Bitmap (1 Bit = 1 Pixel) */
  857.         
  858.         /* erst ins ChipMem kopieren */
  859.         CopyMem( image->data, bwbm->Planes[0], bwbm->BytesPerRow * bwbm->Rows );
  860.         
  861.         /* und dann anzeigen */
  862.         BltBitMapRastPort( bwbm, 0, 0, rp, offx, offy, width, height, 0x030 );
  863.     }
  864.     else if( image->depth == 8 )
  865.     {
  866.         /* Standard 8 Bit Bitmap (chunky pixels) */
  867.         
  868.         WritePixelArray8( rp, offx, offy, offx+width-1, offy+height-1, image->data, temprp );
  869.     }
  870.     else if( image->depth >= 24 )
  871.     {
  872.         /* ham not yet implemented */
  873.     }
  874.     
  875.     /* CloseGadget abfragen */
  876.     
  877.     if( mpeg_window )
  878.     {
  879.         while( imsg = (struct IntuiMessage *) GetMsg(mpeg_window->UserPort) )
  880.         {
  881.             class = imsg->Class;
  882.             ReplyMsg( (struct Message *) imsg );
  883.             
  884.             if( class == CLOSEWINDOW )
  885.                 exit( 0 );
  886.         }
  887.     }
  888.     
  889.     /* Bild abspeichern */
  890.     
  891.     if( saveFlag )
  892.     {
  893.         static long frame = 0;
  894.         static char framename[ 256 ];
  895.         
  896.         sprintf( framename, saveiff_option, frame++ );
  897.         
  898.         if( image->depth <= 8 )
  899.         {
  900.             /* Palettenmodus */
  901.             
  902.             int w = rp->BitMap->BytesPerRow * 8,
  903.                 h = rp->BitMap->Rows;
  904.             int cc = 1 << rp->BitMap->Depth;
  905.             
  906.             if( rev3 )
  907.             {
  908.                 ULONG colortable[256 * 3];
  909.                 
  910.                 GetRGB32( cm, 0, cc, colortable );
  911.                 
  912.                 saveilbm( ilbm, rp->BitMap, GetVPModeID(vp),
  913.                     w, h, w, h, colortable, cc, 32,
  914.                     mskNone, 0, NULL, NULL, framename );
  915.             }
  916.             else
  917.             {
  918.                 UWORD colortable[256];
  919.                 int i;
  920.                 
  921.                 for( i=0; i<cc; i++ )
  922.                     colortable[i] = GetRGB4( cm, i );
  923.                 
  924.                 saveilbm( ilbm, rp->BitMap, GetVPModeID(vp),
  925.                     w, h, w, h, colortable, cc, 4,
  926.                     mskNone, 0, NULL, NULL, framename );
  927.             }
  928.         }
  929.         else
  930.         {
  931.             /* True-Color */
  932.             
  933.             /* R, G und B-Arrays füllen */
  934.             {
  935.                 unsigned char *i = image->data, *rp, *gp, *bp;
  936.                 long c = width * height;
  937.                 
  938.                 rp = rsrc;
  939.                 gp = gsrc;
  940.                 bp = bsrc;
  941.                 
  942.                 while( c-- )
  943.                 {
  944.                     i++;
  945.                     *bp++ = *i++;
  946.                     *gp++ = *i++;
  947.                     *rp++ = *i++;
  948.                 }
  949.             }
  950.             
  951.             /* Konvertieren */
  952.             {
  953.                 WritePixelArray8( rrp, 0, 0, width-1, height-1, rsrc, rtemprp );
  954.                 WritePixelArray8( grp, 0, 0, width-1, height-1, gsrc, gtemprp );
  955.                 WritePixelArray8( brp, 0, 0, width-1, height-1, bsrc, btemprp );
  956.             }
  957.             
  958.             /* Speichern */
  959.             {
  960.                 int w = bm24->BytesPerRow * 8,
  961.                     h = bm24->Rows;
  962.                 
  963.                 saveilbm( ilbm, bm24, 0,
  964.                     w, h, w, h, NULL, 0, 0,
  965.                     mskNone, 0, NULL, NULL, framename );
  966.             }
  967.         }
  968.     }
  969. }
  970.  
  971.  
  972. /***************************************************************/
  973.  
  974.  
  975. Colormap XCreateColormap(
  976.     Display*        display,
  977.     Window            w,
  978.     Visual*            visual,
  979.     int                alloc )
  980. {
  981.     return 1;
  982. }
  983.  
  984.  
  985. Colormap XDefaultColormap(
  986.     Display*        display,
  987.     int                screen_number )
  988. {
  989.     return 1;
  990. }
  991.  
  992.  
  993. Status XAllocColor(
  994.     Display*        display,
  995.     Colormap        colormap,
  996.     XColor*            xcolor )
  997. {
  998.     long color;
  999.     
  1000.     if( rev3 )
  1001.         color = ObtainBestPenA( cm,
  1002.             xcolor->red << 16, xcolor->green << 16, xcolor->blue << 16,
  1003.             NULL );
  1004.     else
  1005.         color = myObtainBestPenA( cm,
  1006.             xcolor->red << 16, xcolor->green << 16, xcolor->blue << 16,
  1007.             NULL );
  1008.     
  1009.     used_colors[ used_cnt++ ] = color;
  1010.     xcolor->pixel = color;
  1011.     
  1012.     return color;
  1013. }
  1014.  
  1015.  
  1016. /***************************************************************/
  1017.  
  1018.  
  1019. XFree( void *data )
  1020. {
  1021. }
  1022.  
  1023.  
  1024.