home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga Shareware Floppies / ma57.dms / ma57.adf / aMiPEG05 / source.lha / ham8.c < prev    next >
C/C++ Source or Header  |  1996-01-09  |  10KB  |  405 lines

  1. /*
  2.  *  This source copes with all amiga-specific stuff as opening the screen, resizing
  3.  *  it using user copper lists, etc.
  4.  *
  5.  *  Copper-based resizing is now implemented, although no aspect ratio is taken care of.
  6.  *
  7.  *  HAM6 is supported now.
  8.  *
  9.  *  Michael Rausch  14-4-94  1:11:59
  10.  */
  11.  
  12. #include <proto/exec.h>
  13. #include <proto/intuition.h>
  14. #include <proto/graphics.h>
  15.  
  16. #include <exec/memory.h>
  17. #include <hardware/custom.h>
  18. #include <graphics/copper.h>
  19. #include <graphics/gfxbase.h>
  20. #include <graphics/gfxmacros.h>
  21. #include <graphics/videocontrol.h>
  22. #include <graphics/displayinfo.h>
  23. #include <graphics/display.h>
  24.  
  25. #include <dos/dos.h>
  26. #include <proto/dos.h>
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31.  
  32. #include "video.h"
  33. #include "proto.h"
  34. extern int ditherType;
  35.  
  36. extern void HAM8_Init(struct RastPort *);    // kinda static
  37. extern void HAM8_Init_lores(struct RastPort *);
  38. extern void HAM6_Init_lores(struct RastPort *);
  39.  
  40. void (*HAM8_draw)(void *, int, int);
  41.  
  42.  
  43. #define custom ((*(volatile struct Custom *)(0xdff000)))
  44.  
  45.  
  46. struct IntuitionBase *IntuitionBase;
  47. struct GfxBase *GfxBase;
  48. extern struct ExecBase *SysBase;
  49. static struct Screen *screen;
  50. static ULONG soerror = NULL;
  51.  
  52. int gfxver;
  53. ULONG *kaiko = NULL;
  54.  
  55. int lores=TRUE, sdbl=TRUE, ham6=FALSE;
  56.  
  57. int max_x, max_y;
  58.  
  59. static struct ColorSpec firstblack[2]={ {0,0,0,0}, {-1, 0,0,0} };    /* Color 0 is 0x000*/
  60.  
  61.  
  62. static void Quit(char *why, int failcode)
  63. {
  64.     puts(why);
  65.     exit(failcode);
  66. }
  67.  
  68. static void output_term(void)
  69. {
  70.     if (screen)
  71.     {
  72.         FreeVPortCopLists(&(screen->ViewPort));
  73.         RemakeDisplay();
  74.         CloseScreen(screen);
  75.     }
  76.     if (IntuitionBase) CloseLibrary((struct Library *) IntuitionBase);
  77.     if (GfxBase) CloseLibrary((struct Library *) GfxBase);
  78. }
  79.  
  80.  
  81. void InitColorDisplay(char *name)
  82. {
  83.     atexit(output_term);
  84.  
  85.     if ((GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",37))==NULL)
  86.         Quit("graphics.library is too old, <V39",25);
  87.     if ((IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",37))==NULL)
  88.         Quit("intuition.library is too old, <V39",25);
  89.  
  90.     gfxver = GfxBase->LibNode.lib_Version;
  91.     if(gfxver>=40) kaiko = GfxBase->ChunkyToPlanarPtr;
  92.  
  93.     HAM8_draw = (void (*)(void *, int, int)) NoDitherImage;    // method casting ... argh!
  94.     DoDitherImage = NoDitherImage;
  95. }
  96.  
  97.  
  98. /*
  99.  *   Resize the display using a copper list. Nifty'n neat amiga feature.
  100.  *
  101.  *   Phew ... takes now 2 hours to fiddle the system-compliant custom modulo stuff.
  102.  */
  103. void ResizeDisplay(int w, int h)
  104. {
  105.     struct UCopList *ucoplist;
  106.     static struct TagItem uCopTags[] = {
  107.         { VC_NoColorPaletteLoad, TRUE },
  108.         { VTAG_USERCLIP_SET, NULL },
  109.         { VTAG_END_CM, NULL }};
  110.     int i,j,k, y, fp_each, locallores;
  111.     struct CopList *dspins;
  112.     struct CopIns *copins;
  113.     short bpl1mod=-1, bpl2mod=-1, last1, last2, this1, this2;
  114.     ULONG id;
  115.     struct DimensionInfo dim_info;
  116.     char pubscreenname[MAXPUBSCREENNAME];
  117.     struct Screen *pubscreen;
  118.     BOOL quit = FALSE;
  119.     struct IntuiMessage *msg;
  120.     static char win_title[256];
  121.  
  122.     if(ditherType == NO_DITHER) return;
  123.  
  124.     if(ditherType == CYBERGFX_DITHER || ditherType == CYBERGFXGRAY_DITHER)
  125.     {
  126.         ModifyIDCMP(cyber_window, IDCMP_NEWSIZE);
  127.  
  128.         SizeWindow(cyber_window, w - 160, h - 120);
  129.  
  130.         sprintf(win_title, "%s [%dx%d]", FilePart(animname), w, h);
  131.         SetWindowTitles(cyber_window, win_title, (UBYTE *)~0);
  132.  
  133.         while(!quit)
  134.         {
  135.             WaitPort(cyber_window->UserPort);
  136.             while(msg = (struct IntuiMessage *)GetMsg(cyber_window->UserPort))
  137.             {
  138.                 if(msg->Class == IDCMP_NEWSIZE)
  139.                     quit = TRUE;
  140.  
  141.                 ReplyMsg((struct Message *)msg);
  142.             }
  143.         }
  144.  
  145.         ModifyIDCMP(cyber_window, CLOSEWINDOW | MOUSEBUTTONS);
  146.  
  147.         original_x = cyber_window->Width;
  148.         original_y = cyber_window->Height;
  149.         return;
  150.     }
  151.  
  152.     GetDefaultPubScreen(pubscreenname);
  153.     pubscreen = LockPubScreen(pubscreenname);
  154.     id = GetVPModeID(&(pubscreen->ViewPort)) & MONITOR_ID_MASK;
  155.     UnlockPubScreen(NULL, pubscreen);
  156.  
  157.     if (GetDisplayInfoData(FindDisplayInfo(id), (UBYTE *)&dim_info, sizeof(struct DimensionInfo), DTAG_DIMS, 0))
  158.         max_y=dim_info.StdOScan.MaxY - dim_info.StdOScan.MinY + 1;
  159.     else
  160.         max_y=200;
  161.  
  162.     if(h>max_y)
  163.         sdbl=FALSE, max_y<<=1;
  164.  
  165.     if(!(GfxBase->ChipRevBits0 & (GFXF_AA_ALICE|GFXF_AA_LISA)))
  166.         ham6 = TRUE;
  167.  
  168.     if(ham6)
  169.         lores=TRUE;
  170.     locallores = lores && (w<=160);
  171.     max_x = (locallores ? 320 : 640);
  172.  
  173.     switch(id)
  174.     {
  175.         case A2024_MONITOR_ID:
  176.             Quit("Get some colors, dude.", 25);
  177.  
  178.         case DBLPAL_MONITOR_ID: /* ARGH!  Kick their butts for this one! */
  179.             if(sdbl)
  180.                 id = locallores ? DBLPALLORESHAMFF_KEY : DBLPALHIRESHAMFF_KEY;
  181.             else
  182.                 id = locallores ? DBLPALLORESHAM_KEY : DBLPALHIRESHAM_KEY;
  183.             break;
  184.  
  185.         case DBLNTSC_MONITOR_ID:
  186.             if(sdbl)
  187.                 id = locallores ? DBLNTSCLORESHAMFF_KEY : DBLNTSCHIRESHAMFF_KEY;
  188.             else
  189.                 id = locallores ? DBLNTSCLORESHAM_KEY : DBLNTSCHIRESHAM_KEY;
  190.             break;
  191.  
  192.         case EURO72_MONITOR_ID:
  193.             if(sdbl)
  194.                 id = locallores ? EURO72LORESHAMDBL_KEY : EURO72PRODUCTHAMDBL_KEY;
  195.             else
  196.                 id = locallores ? EURO72LORESHAM_KEY : EURO72PRODUCTHAM_KEY;
  197.             break;
  198.  
  199.         case VGA_MONITOR_ID:
  200.             if(sdbl)
  201.                 id = locallores ? VGALORESHAMDBL_KEY : VGAPRODUCTHAMDBL_KEY;
  202.             else
  203.                 id = locallores ? VGALORESHAM_KEY : VGAPRODUCTHAM_KEY;
  204.             break;
  205.  
  206.         case DEFAULT_MONITOR_ID:
  207.         case PAL_MONITOR_ID:
  208.         case NTSC_MONITOR_ID:
  209.             if(gfxver >= 40 && sdbl)
  210.                 id = locallores ? LORESHAMSDBL_KEY: HIRESHAMSDBL_KEY;
  211.             else
  212.                 sdbl=FALSE, id = locallores ? HAM_KEY : HIRESHAM_KEY;
  213.             break;
  214.  
  215.         default:
  216.             printf("ModeID is %x\n", id);
  217.             Quit("*shrug*  strange monitor.", 10);
  218.     }
  219.  
  220.     if(!(screen=OpenScreenTags(NULL,
  221.         SA_DisplayID,    id,
  222.         SA_Depth,    ham6?6:8,
  223.         SA_Width,    max_x,
  224.         SA_Colors,    firstblack,
  225.         SA_Type,    CUSTOMSCREEN|SCREENQUIET,
  226.         SA_Quiet,     TRUE,
  227.         SA_Interleaved,    !ham6, //TRUE,
  228.         SA_Overscan,    OSCAN_STANDARD,
  229.         SA_MinimizeISG,    TRUE,
  230.         SA_ErrorCode,    &soerror,
  231.         TAG_END))) Quit("Couldn't open screen.",25);
  232.  
  233.     if((screen->RastPort.BitMap->Depth == 6) && !ham6)
  234.         Quit("Incorrect depth. Please try to specify \"-dither ham6\" explicitely.",25);
  235.  
  236.     if(lores) {
  237.         if(ham6)
  238.         {    // the new ham6 routines do not handle interleaved bitmaps anymore
  239.             HAM6_Init_lores(&(screen->RastPort));
  240.             HAM8_draw = HAM6_draw_lores;
  241.             DoDitherImage = ColorDitherImage_12bit;
  242.         } else {
  243.             HAM8_Init_lores(&(screen->RastPort));
  244.             HAM8_draw = HAM8_draw_lores;
  245.             DoDitherImage = ColorDitherImage_lores;    // lacks kaiko support, actually
  246.         }
  247.         max_x >>=1;
  248.  
  249.     } else {
  250.         HAM8_Init(&(screen->RastPort));
  251.         HAM8_draw = HAM8_draw_hires;
  252.         DoDitherImage = ColorDitherImage;    // kaiko on one day
  253.         max_x >>=2;
  254.     }
  255.  
  256.     if(noDisplayFlag)
  257.         HAM8_draw = (void (*)(void *, int, int)) NoDitherImage;    // method casting ... argh!
  258.  
  259.  
  260.     /* the memory is freed upon exit in output_term via FreeVPortCopLists */
  261.     if(!(ucoplist = AllocMem(sizeof(struct UCopList), MEMF_PUBLIC|MEMF_CLEAR)))
  262.         Quit("No memory for copper list.",25);
  263.  
  264.     /* fiddle out some hardware values from this screen's init copper list */
  265.     dspins=screen->ViewPort.DspIns;
  266.     copins=dspins->CopIns;
  267.     for(i=dspins->Count-1; i>=0; i--, copins++)
  268.     {
  269.         j = copins->DESTDATA;
  270.  
  271.         switch(copins->DESTADDR & 0xfff)    // argh! kick 2.1 messes this up!
  272.         {        
  273.             case (int)&((*(struct Custom *)(0)).bpl1mod):
  274.                 last1=bpl1mod = j;
  275.                 break;
  276.             case (int)&((*(struct Custom *)(0)).bpl2mod):
  277.                 last2=bpl2mod = j;
  278.                 break;
  279.         }
  280.     }
  281.  
  282.     if(bpl1mod==-1 || bpl2mod==-1)
  283.     {
  284.         printf("ooops\n");
  285.         return;    /* hmmm? */
  286.     }
  287.  
  288.     if((bpl1mod == bpl2mod) && sdbl) sdbl=FALSE;
  289.  
  290.     y = screen->Height;
  291.     (void) CINIT(ucoplist, y*3);        /* ... instructions per line */
  292.  
  293.  
  294.     if(sdbl)
  295.     {
  296.         /*
  297.          *  We abuse some of AGA's features here; double-scanning is implemented
  298.          *  by applying bpl1mod to ALL planes on one line, bpl2mod on the next.
  299.          *  Obviously, double-scanning enables some kind of internal chipmem cache.
  300.          *  At least, it's faster. And (because of?) less copper instructions.
  301.          */
  302.  
  303.         fp_each = ((y*2)<<8) / (short)h;
  304.         for(k=fp_each, j=0; j<y; j++)                /* for each line in the display */
  305.         {
  306.  
  307.             if((k-=0x100)>=0x100)                /* we still gotta double the line */
  308.                 this1=bpl1mod;
  309.             else                        /* finally, we are ready; next one */
  310.                 this1=bpl2mod, k=(k&0xff)+fp_each;
  311.  
  312.             if((k-=0x100)>=0x100)                /* we still gotta double the line */
  313.                 this2=bpl1mod;
  314.             else                        /* finally, we are ready; next one */
  315.                 this2=bpl2mod, k=(k&0xff)+fp_each;
  316.  
  317.             if(last1!=this1 || last2!=this2)
  318.                 CWAIT(ucoplist, j, 0);
  319.  
  320.             if(last1!=this1)
  321.             {
  322.                 CMOVE(ucoplist, custom.bpl1mod, this1);
  323.                 last1=this1;
  324.             }
  325.  
  326.             if(last2!=this2)
  327.             {
  328.                 CMOVE(ucoplist, custom.bpl2mod, this2);
  329.                 last2=this2;
  330.             }
  331.         }
  332.     } else {
  333.         /*
  334.          *  No scan-doubling possible; most probably because of a pal/ntsc screen 
  335.          *  and no V40 graphics library available.
  336.          */
  337.  
  338.         bpl1mod -= screen->RastPort.BitMap->BytesPerRow;
  339.  
  340.         fp_each = (y<<8) / (short)h;
  341.         for(k=fp_each, j=0; j<y; j++)                /* for each line in the display */
  342.         {
  343.  
  344.             if((k-=0x100)>=0x100)                /* we still gotta double the line */
  345.                 this1=bpl1mod;
  346.             else                        /* finally, we are ready; next one */
  347.                 this1=bpl2mod, k=(k&0xff)+fp_each;
  348.  
  349.             if(last1!=this1)
  350.             {
  351.                 CWAIT(ucoplist, j, 0);
  352.                 CMOVE(ucoplist, custom.bpl1mod, this1);
  353.                 CMOVE(ucoplist, custom.bpl2mod, this1);
  354.                 last1=this1;
  355.             }
  356.         }
  357.     }
  358.  
  359.     /*
  360.      *  Pretty nifty, isn't it? Finally, even a little bit copper-list-optimizing is build in!
  361.      */
  362.  
  363.     CEND(ucoplist);
  364.  
  365.     /* Set the freshly created user copper list */
  366.     //Forbid();
  367.     screen->ViewPort.UCopIns = ucoplist;
  368.     //Permit();
  369.  
  370.     /*  Enable user copper list clipping for this ViewPort.  */
  371.     (void) VideoControl( screen->ViewPort.ColorMap, uCopTags );
  372.  
  373.     RethinkDisplay();
  374. }
  375.  
  376.  
  377.  
  378. /*
  379.  *--------------------------------------------------------------
  380.  *
  381.  * InitGrayDisplay --
  382.  *
  383.  *    Initialized display for gray scale dither.
  384.  *
  385.  * Results:
  386.  *      None.
  387.  *
  388.  * Side effects:
  389.  *      None.
  390.  *
  391.  *--------------------------------------------------------------
  392.  */
  393.  
  394. #define NUM_COLORS 128
  395.  
  396. void InitGrayDisplay(char *name)
  397. {
  398.     Quit("Not implemented, yet.\n", 0);
  399.  
  400.     DoDitherImage = GrayDitherImage;
  401. }
  402.  
  403.  
  404.  
  405.