home *** CD-ROM | disk | FTP | other *** search
- /*
- * This source copes with all amiga-specific stuff as opening the screen, resizing
- * it using user copper lists, etc.
- *
- * Copper-based resizing is now implemented, although no aspect ratio is taken care of.
- *
- * HAM6 is supported now.
- *
- * Michael Rausch 14-4-94 1:11:59
- */
-
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
-
- #include <exec/memory.h>
- #include <hardware/custom.h>
- #include <graphics/copper.h>
- #include <graphics/gfxbase.h>
- #include <graphics/gfxmacros.h>
- #include <graphics/videocontrol.h>
- #include <graphics/displayinfo.h>
- #include <graphics/display.h>
-
- #include <dos/dos.h>
- #include <proto/dos.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "video.h"
- #include "proto.h"
- extern int ditherType;
-
- extern void HAM8_Init(struct RastPort *); // kinda static
- extern void HAM8_Init_lores(struct RastPort *);
- extern void HAM6_Init_lores(struct RastPort *);
-
- void (*HAM8_draw)(void *, int, int);
-
-
- #define custom ((*(volatile struct Custom *)(0xdff000)))
-
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- extern struct ExecBase *SysBase;
- static struct Screen *screen;
- static ULONG soerror = NULL;
-
- int gfxver;
- ULONG *kaiko = NULL;
-
- int lores=TRUE, sdbl=TRUE, ham6=FALSE;
-
- int max_x, max_y;
-
- static struct ColorSpec firstblack[2]={ {0,0,0,0}, {-1, 0,0,0} }; /* Color 0 is 0x000*/
-
-
- static void Quit(char *why, int failcode)
- {
- puts(why);
- exit(failcode);
- }
-
- static void output_term(void)
- {
- if (screen)
- {
- FreeVPortCopLists(&(screen->ViewPort));
- RemakeDisplay();
- CloseScreen(screen);
- }
- if (IntuitionBase) CloseLibrary((struct Library *) IntuitionBase);
- if (GfxBase) CloseLibrary((struct Library *) GfxBase);
- }
-
-
- void InitColorDisplay(char *name)
- {
- atexit(output_term);
-
- if ((GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",37))==NULL)
- Quit("graphics.library is too old, <V39",25);
- if ((IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",37))==NULL)
- Quit("intuition.library is too old, <V39",25);
-
- gfxver = GfxBase->LibNode.lib_Version;
- if(gfxver>=40) kaiko = GfxBase->ChunkyToPlanarPtr;
-
- HAM8_draw = (void (*)(void *, int, int)) NoDitherImage; // method casting ... argh!
- DoDitherImage = NoDitherImage;
- }
-
-
- /*
- * Resize the display using a copper list. Nifty'n neat amiga feature.
- *
- * Phew ... takes now 2 hours to fiddle the system-compliant custom modulo stuff.
- */
- void ResizeDisplay(int w, int h)
- {
- struct UCopList *ucoplist;
- static struct TagItem uCopTags[] = {
- { VC_NoColorPaletteLoad, TRUE },
- { VTAG_USERCLIP_SET, NULL },
- { VTAG_END_CM, NULL }};
- int i,j,k, y, fp_each, locallores;
- struct CopList *dspins;
- struct CopIns *copins;
- short bpl1mod=-1, bpl2mod=-1, last1, last2, this1, this2;
- ULONG id;
- struct DimensionInfo dim_info;
- char pubscreenname[MAXPUBSCREENNAME];
- struct Screen *pubscreen;
- BOOL quit = FALSE;
- struct IntuiMessage *msg;
- static char win_title[256];
-
- if(ditherType == NO_DITHER) return;
-
- if(ditherType == CYBERGFX_DITHER || ditherType == CYBERGFXGRAY_DITHER)
- {
- ModifyIDCMP(cyber_window, IDCMP_NEWSIZE);
-
- SizeWindow(cyber_window, w - 160, h - 120);
-
- sprintf(win_title, "%s [%dx%d]", FilePart(animname), w, h);
- SetWindowTitles(cyber_window, win_title, (UBYTE *)~0);
-
- while(!quit)
- {
- WaitPort(cyber_window->UserPort);
- while(msg = (struct IntuiMessage *)GetMsg(cyber_window->UserPort))
- {
- if(msg->Class == IDCMP_NEWSIZE)
- quit = TRUE;
-
- ReplyMsg((struct Message *)msg);
- }
- }
-
- ModifyIDCMP(cyber_window, CLOSEWINDOW | MOUSEBUTTONS);
-
- original_x = cyber_window->Width;
- original_y = cyber_window->Height;
- return;
- }
-
- GetDefaultPubScreen(pubscreenname);
- pubscreen = LockPubScreen(pubscreenname);
- id = GetVPModeID(&(pubscreen->ViewPort)) & MONITOR_ID_MASK;
- UnlockPubScreen(NULL, pubscreen);
-
- if (GetDisplayInfoData(FindDisplayInfo(id), (UBYTE *)&dim_info, sizeof(struct DimensionInfo), DTAG_DIMS, 0))
- max_y=dim_info.StdOScan.MaxY - dim_info.StdOScan.MinY + 1;
- else
- max_y=200;
-
- if(h>max_y)
- sdbl=FALSE, max_y<<=1;
-
- if(!(GfxBase->ChipRevBits0 & (GFXF_AA_ALICE|GFXF_AA_LISA)))
- ham6 = TRUE;
-
- if(ham6)
- lores=TRUE;
- locallores = lores && (w<=160);
- max_x = (locallores ? 320 : 640);
-
- switch(id)
- {
- case A2024_MONITOR_ID:
- Quit("Get some colors, dude.", 25);
-
- case DBLPAL_MONITOR_ID: /* ARGH! Kick their butts for this one! */
- if(sdbl)
- id = locallores ? DBLPALLORESHAMFF_KEY : DBLPALHIRESHAMFF_KEY;
- else
- id = locallores ? DBLPALLORESHAM_KEY : DBLPALHIRESHAM_KEY;
- break;
-
- case DBLNTSC_MONITOR_ID:
- if(sdbl)
- id = locallores ? DBLNTSCLORESHAMFF_KEY : DBLNTSCHIRESHAMFF_KEY;
- else
- id = locallores ? DBLNTSCLORESHAM_KEY : DBLNTSCHIRESHAM_KEY;
- break;
-
- case EURO72_MONITOR_ID:
- if(sdbl)
- id = locallores ? EURO72LORESHAMDBL_KEY : EURO72PRODUCTHAMDBL_KEY;
- else
- id = locallores ? EURO72LORESHAM_KEY : EURO72PRODUCTHAM_KEY;
- break;
-
- case VGA_MONITOR_ID:
- if(sdbl)
- id = locallores ? VGALORESHAMDBL_KEY : VGAPRODUCTHAMDBL_KEY;
- else
- id = locallores ? VGALORESHAM_KEY : VGAPRODUCTHAM_KEY;
- break;
-
- case DEFAULT_MONITOR_ID:
- case PAL_MONITOR_ID:
- case NTSC_MONITOR_ID:
- if(gfxver >= 40 && sdbl)
- id = locallores ? LORESHAMSDBL_KEY: HIRESHAMSDBL_KEY;
- else
- sdbl=FALSE, id = locallores ? HAM_KEY : HIRESHAM_KEY;
- break;
-
- default:
- printf("ModeID is %x\n", id);
- Quit("*shrug* strange monitor.", 10);
- }
-
- if(!(screen=OpenScreenTags(NULL,
- SA_DisplayID, id,
- SA_Depth, ham6?6:8,
- SA_Width, max_x,
- SA_Colors, firstblack,
- SA_Type, CUSTOMSCREEN|SCREENQUIET,
- SA_Quiet, TRUE,
- SA_Interleaved, !ham6, //TRUE,
- SA_Overscan, OSCAN_STANDARD,
- SA_MinimizeISG, TRUE,
- SA_ErrorCode, &soerror,
- TAG_END))) Quit("Couldn't open screen.",25);
-
- if((screen->RastPort.BitMap->Depth == 6) && !ham6)
- Quit("Incorrect depth. Please try to specify \"-dither ham6\" explicitely.",25);
-
- if(lores) {
- if(ham6)
- { // the new ham6 routines do not handle interleaved bitmaps anymore
- HAM6_Init_lores(&(screen->RastPort));
- HAM8_draw = HAM6_draw_lores;
- DoDitherImage = ColorDitherImage_12bit;
- } else {
- HAM8_Init_lores(&(screen->RastPort));
- HAM8_draw = HAM8_draw_lores;
- DoDitherImage = ColorDitherImage_lores; // lacks kaiko support, actually
- }
- max_x >>=1;
-
- } else {
- HAM8_Init(&(screen->RastPort));
- HAM8_draw = HAM8_draw_hires;
- DoDitherImage = ColorDitherImage; // kaiko on one day
- max_x >>=2;
- }
-
- if(noDisplayFlag)
- HAM8_draw = (void (*)(void *, int, int)) NoDitherImage; // method casting ... argh!
-
-
- /* the memory is freed upon exit in output_term via FreeVPortCopLists */
- if(!(ucoplist = AllocMem(sizeof(struct UCopList), MEMF_PUBLIC|MEMF_CLEAR)))
- Quit("No memory for copper list.",25);
-
- /* fiddle out some hardware values from this screen's init copper list */
- dspins=screen->ViewPort.DspIns;
- copins=dspins->CopIns;
- for(i=dspins->Count-1; i>=0; i--, copins++)
- {
- j = copins->DESTDATA;
-
- switch(copins->DESTADDR & 0xfff) // argh! kick 2.1 messes this up!
- {
- case (int)&((*(struct Custom *)(0)).bpl1mod):
- last1=bpl1mod = j;
- break;
- case (int)&((*(struct Custom *)(0)).bpl2mod):
- last2=bpl2mod = j;
- break;
- }
- }
-
- if(bpl1mod==-1 || bpl2mod==-1)
- {
- printf("ooops\n");
- return; /* hmmm? */
- }
-
- if((bpl1mod == bpl2mod) && sdbl) sdbl=FALSE;
-
- y = screen->Height;
- (void) CINIT(ucoplist, y*3); /* ... instructions per line */
-
-
- if(sdbl)
- {
- /*
- * We abuse some of AGA's features here; double-scanning is implemented
- * by applying bpl1mod to ALL planes on one line, bpl2mod on the next.
- * Obviously, double-scanning enables some kind of internal chipmem cache.
- * At least, it's faster. And (because of?) less copper instructions.
- */
-
- fp_each = ((y*2)<<8) / (short)h;
- for(k=fp_each, j=0; j<y; j++) /* for each line in the display */
- {
-
- if((k-=0x100)>=0x100) /* we still gotta double the line */
- this1=bpl1mod;
- else /* finally, we are ready; next one */
- this1=bpl2mod, k=(k&0xff)+fp_each;
-
- if((k-=0x100)>=0x100) /* we still gotta double the line */
- this2=bpl1mod;
- else /* finally, we are ready; next one */
- this2=bpl2mod, k=(k&0xff)+fp_each;
-
- if(last1!=this1 || last2!=this2)
- CWAIT(ucoplist, j, 0);
-
- if(last1!=this1)
- {
- CMOVE(ucoplist, custom.bpl1mod, this1);
- last1=this1;
- }
-
- if(last2!=this2)
- {
- CMOVE(ucoplist, custom.bpl2mod, this2);
- last2=this2;
- }
- }
- } else {
- /*
- * No scan-doubling possible; most probably because of a pal/ntsc screen
- * and no V40 graphics library available.
- */
-
- bpl1mod -= screen->RastPort.BitMap->BytesPerRow;
-
- fp_each = (y<<8) / (short)h;
- for(k=fp_each, j=0; j<y; j++) /* for each line in the display */
- {
-
- if((k-=0x100)>=0x100) /* we still gotta double the line */
- this1=bpl1mod;
- else /* finally, we are ready; next one */
- this1=bpl2mod, k=(k&0xff)+fp_each;
-
- if(last1!=this1)
- {
- CWAIT(ucoplist, j, 0);
- CMOVE(ucoplist, custom.bpl1mod, this1);
- CMOVE(ucoplist, custom.bpl2mod, this1);
- last1=this1;
- }
- }
- }
-
- /*
- * Pretty nifty, isn't it? Finally, even a little bit copper-list-optimizing is build in!
- */
-
- CEND(ucoplist);
-
- /* Set the freshly created user copper list */
- //Forbid();
- screen->ViewPort.UCopIns = ucoplist;
- //Permit();
-
- /* Enable user copper list clipping for this ViewPort. */
- (void) VideoControl( screen->ViewPort.ColorMap, uCopTags );
-
- RethinkDisplay();
- }
-
-
-
- /*
- *--------------------------------------------------------------
- *
- * InitGrayDisplay --
- *
- * Initialized display for gray scale dither.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- #define NUM_COLORS 128
-
- void InitGrayDisplay(char *name)
- {
- Quit("Not implemented, yet.\n", 0);
-
- DoDitherImage = GrayDitherImage;
- }
-
-
-
-