home *** CD-ROM | disk | FTP | other *** search
-
- #include <exec/types.h>
- #include <dos/rdargs.h>
- #include <devices/printer.h>
- #include <devices/prtgfx.h>
- #include <intuition/screens.h>
- #include <intuition/intuition.h>
- #include <exec/memory.h>
- #include <dos/dos.h>
-
- #include <graphics/gfxmacros.h>
- #include <graphics/copper.h>
- #include <hardware/custom.h>
-
- #include "iff.h"
- #include "2View.h"
- #include "arexx.h"
-
- /*Prototypes*/
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/iffparse_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/alib_protos.h>
-
- /*Pragmas*/
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/intuition_pragmas.h>
- #include <pragmas/graphics_pragmas.h>
- #include <pragmas/iffparse_pragmas.h>
- #include <pragmas/dos_pragmas.h>
-
- BPTR StdErr=NULL; /*'Standard error' for AmigaDOS IO functions*/
-
- /*These are defined in 2View.c, but this file needs to reference them*/
-
- extern struct NewScreen newScreen;
- extern struct NewWindow newWindow;
-
- extern struct IFFHandle *iff; /*IFF handle*/
- extern BPTR pL; /*Playlist file pointer*/
- extern BOOL masking,print,toFront,printPics;
-
- /*A true here indicates the current ILBM file is compressed*/
- extern BYTE Compression;
-
- extern char trashBuf[512]; /* A place to dump mask information */
-
- extern struct Screen *screen;
- extern struct Window *window;
-
- /*The previous screen and window*/
- extern struct Window *prevWindow;
- extern struct Screen *prevScreen;
-
- /*Libraries we'll need*/
- extern struct Library *IFFParseBase;
- extern struct Library *IntuitionBase;
- extern struct Library *GfxBase;
-
- /*Provided by the compiler*/
- extern struct Library *SysBase;
- extern struct Library *DOSBase;
-
- extern BOOL cycle;
- extern UBYTE numColors;
- UWORD colorTable[32];
- extern UWORD destMap[32];
-
- extern struct Custom custom;
-
- /*Convert the CMAP information into a color map, then set the colors*/
- /*of the screen according to that colormap*/
- void setScreenColors(struct Screen *scr, UBYTE *colorMap, UBYTE depth,
- UWORD *destColorMap,UBYTE *colors)
- {
- int i,numColors;
-
- numColors=1<<depth; /*Get the number of colors (generally 2^depth)*/
-
- if(newScreen.ViewModes & HAM) /*There are, of course, 2 exceptions*/
- numColors=16;
- if(newScreen.ViewModes & EXTRA_HALFBRITE)
- numColors=32;
-
- /*For each color, convert it from CMAP to Amiga form and*/
- /*store it (both in an unchanging table (colorTable) and in a "work" */
- /*table (destColorMap), where the values are free to change during */
- /*color cycling, etc.*/
- for(i=0;i<numColors;i++)
- colorTable[i]=destColorMap[i]=
- (15 & (colorMap[i*3])>>4)<<8 | (15 & (colorMap[i*3+1])>>4)<<4 |
- (15 & (colorMap[i*3+2]>>4));
-
- /*Store the color table*/
- LoadRGB4(&(scr->ViewPort),destColorMap,numColors);
-
- /*Return the number of colors*/
- *colors=numColors;
-
- return;
- }
-
- /*Make a newScreen structure using the BMHD chunk*/
- void getBMHD(struct BitMapHeader *bmhd)
- {
- /*Define the screen as hires if*/
- if(bmhd->PageWidth > 400 && bmhd->PageWidth <=704 && bmhd->nplanes < 5)
- newScreen.ViewModes|=HIRES; /*wider than 400 pixels and not */
- /*deeper than 4 bitplanes*/
-
- if(bmhd->PageHeight > 300 && bmhd->PageHeight <=512) /*Define the screen as interlaced*/
- newScreen.ViewModes|=LACE; /*if the height is > 300 pixels*/
-
- newScreen.Width=bmhd->w; /*Store the rest of the values*/
- newScreen.Height=bmhd->h;
-
- newScreen.LeftEdge=bmhd->x;
- newScreen.TopEdge=bmhd->y;
- newScreen.Depth=bmhd->nplanes;
-
- masking=(bmhd->Masking == 1);
-
- Compression=bmhd->Compression; /*Compression flag. Store for*/
- /*later use*/
- return;
- }
-
- /*Data structures for ReadArgs()*/
- struct RDArgs ra=
- {
- {NULL,0,0},
- NULL,
- trashBuf,
- 512,
- "FILE/A/M,SECS=SECONDS/K/N,TICKS/K/N,LOOP/S,FROM/K,PRINT/S"
- };
-
- /*Parse the argument list, using ReadArgs()*/
- void ParseArgs(ULONG *args)
- {
- ReadArgs("FILE/A/M,SECS=SECONDS/K/N,TICKS/K/N,LOOP/S,FROM/K,PRINT/S",
- args,&ra);
- return;
- }
-
- /*Check to see which mouse buttons have been pressed*/
- ButtonTypes checkButton(void)
- {
- struct IntuiMessage *mesg;
- ButtonTypes Button=none;
- static justActivated=FALSE;
-
- /*This function disregards a select (left) mouse button click*/
- /*if the window's just been activated. This is so that a user*/
- /*can click on another window, then make this one active again,*/
- /*without advancing to the next picture*/
-
- /*While there are messages to be read...*/
- while((mesg=(struct IntuiMessage *)GetMsg(prevWindow->UserPort))!=NULL)
- {
- /*Interpret them*/
- switch(mesg->Class)
- {
- case ACTIVEWINDOW: /*Set the appropriate flag if the window*/
- justActivated=TRUE; /*was just activated*/
- break;
- case VANILLAKEY:
- switch(mesg->Code)
- {
- case 16: /*CTRL-P - Print (if this picture hasn't been*/
- if(print) /*printed; this is designed in case the user*/
- { /*holds down CTRL-P: we don't want 10-20 */
- /*print requests to get queued up */
- dumpRastPort(&(prevScreen->RastPort),
- &(prevScreen->ViewPort));
- print=FALSE;
- }
- break;
- case 4: /*CTRL-D - Abort everything*/
- Button=menu;
- break;
- case 3:
- Button=select; /*CTRL-C - Advance to next picture*/
- break;
- case 9: /*TAB: Switch color cycling on/off*/
- toggleCycling();
- break;
-
- }
- break;
- case MOUSEBUTTONS: /*Interpret a button click*/
- if(mesg->Code==SELECTDOWN) /*If the left button was pushed,*/
- if(justActivated) /*and not so as to activate the*/
- { /*window, advance to the next*/
- justActivated=FALSE; /*screen*/
- break;
- }
- else
- Button=select;
- else if(mesg->Code == MENUDOWN) /*If the right button was*/
- Button=menu; /*pushed, we'll want to*/
- break; /*abort*/
- }
- ReplyMsg((struct Message *)mesg); /*Reply to the message*/
- }
- return(Button); /*Return the results*/
- }
-
- /*Toggle color cycling on and off*/
- void toggleCycling(void)
- {
- int c;
-
- cycle=(cycle) ? FALSE : TRUE; /*Toggle the color cycling lag*/
- LoadRGB4(&(prevScreen->ViewPort),colorTable,numColors);
- for(c=0;c<numColors;c++)
- destMap[c]=colorTable[c];
- }
-
-
- struct EasyStruct erError2Line =
- {
- sizeof(struct EasyStruct),
- 0,
- "Program error: 2View",
- "%s\n%s\n%s",
- "Ok"
- };
-
- struct EasyStruct erError1Line =
- {
- sizeof(struct EasyStruct),
- 0,
- "Program error: 2View",
- "%s\n%s",
- "Ok"
- };
-
- /*This prints an error to the console, if we were run from the CLI*/
- /*This is done instead of using Output() so as to get around any redirection*/
- /*that may be in place (just like the standard C stderr)*/
- /*If we can't open a StdErr or 2View was run from Workbench, a requester */
- /*is put up*/
- void printError(char *error1,char *error2)
- {
- if(StdErr==NULL)
- StdErr=Open("CONSOLE:",MODE_OLDFILE);
-
- /* If we can't open StdErr, or Output()==NULL (meaning we're running */
- /* Workbench), put up a requester */
- if(StdErr==NULL || Output()==NULL)
- {
- if(error2==NULL || error2[0]==NULL)
- EasyRequest(NULL,&erError1Line,NULL,error1,"Exiting...");
- else
- EasyRequest(NULL,&erError2Line,NULL,error1,error2,"Exiting...");
- }
- else
- {
- FPuts(StdErr,error1);
- FPuts(StdErr,error2);
- FPuts(StdErr,"\nExiting\n");
- }
- return;
- }
-
- /*Free allocated resources in anticipation of quitting*/
- void cleanup()
- {
- /*Close the ARexx port*/
- dnRexxPort();
-
- /*Close the standard-error file if opened*/
- if(StdErr!=NULL)
- Close(StdErr);
-
- /*Close a previous screen and window, if open*/
- if(prevWindow!=NULL)
- CloseWindow(prevWindow);
- if(prevScreen!=NULL)
- CloseScreen(prevScreen);
-
- /*Close a current screen and window, if open*/
- if(window!=NULL)
- CloseWindow(window);
- if(screen!=NULL)
- CloseScreen(screen);
-
- if(iff!=NULL)
- FreeIFF(iff);
-
- if(pL!=NULL)
- Close(pL);
-
- if(IFFParseBase!=NULL)
- CloseLibrary(IFFParseBase);
-
- if(IntuitionBase!=NULL)
- CloseLibrary(IntuitionBase);
-
- if(GfxBase!=NULL)
- CloseLibrary(GfxBase);
- }
-
- /*Print the specified RastPort (whose ViewPort is pointed to by vp*/
- BOOL dumpRastPort(struct RastPort *rp,struct ViewPort *vp)
- {
- struct IODRPReq *printerMsg;
- struct MsgPort *printerPort;
- static BOOL ableToPrint=TRUE;
-
- if(ableToPrint)
- {
- ableToPrint=FALSE;
- printerPort=CreatePort("2View.print.port",0);
- if(printerPort!=NULL)
- {
- printerMsg=(struct IORequest *)CreateExtIO(printerPort,
- (long)sizeof(struct IODRPReq));
-
- if(printerMsg != NULL)
- {
- /*Open the printer device*/
- if(OpenDevice("printer.device",0,printerMsg,0)==0)
- {
- /*Set up the IODRPReq structure*/
- printerMsg->io_Command=PRD_DUMPRPORT;
- printerMsg->io_RastPort=rp;
- printerMsg->io_ColorMap=vp->ColorMap;
- printerMsg->io_Modes=vp->Modes;
- printerMsg->io_SrcX=0;
- printerMsg->io_SrcY=0;
- printerMsg->io_SrcWidth=vp->DWidth;
- printerMsg->io_SrcHeight=vp->DHeight;
- printerMsg->io_Special=SPECIAL_ASPECT|SPECIAL_FULLROWS|
- SPECIAL_FULLCOLS;
-
- /*Do it*/
- if(DoIO(printerMsg)==0)
- ableToPrint=TRUE;
-
- CloseDevice(printerMsg);
- }
- DeleteExtIO(printerMsg);
- }
- DeletePort(printerPort);
- }
- return(ableToPrint);
- }
- }
-
- /*Determine which colors to cycle, for a CRNG*/
- UBYTE interpretCRNG(UBYTE *cycleTable,CRNG *crng,UBYTE *rate)
- {
- UBYTE length=0;
- UBYTE pos,color;
-
- /*If the rate is zero, colors won't cycle anyway, so return 0*/
- if(crng->rate==0)
- return(0);
-
- /*Get the cycle rate*/
- *rate=16384/crng->rate;
-
- /*If the colors are actually suppossed to be cycling...*/
- if(crng->active!=0)
- {
- /*Get the number of colors to cycle*/
- length=crng->high-crng->low+1;
-
- /*If there are colors to cycle*/
- if(length!=0)
- if(crng->active==1)
- /*Forward cycling*/
- for(pos=0,color=crng->low;pos<length;pos++,color++)
- cycleTable[pos]=color;
- else
- /*Backward cycling*/
- for(pos=0,color=crng->high;pos<length;pos++,color--)
- cycleTable[pos]=color;
- }
- return(length);
- }
-
- UBYTE interpretDRNG(UBYTE *cycleTable,DRNG *drng,UBYTE *rate)
- {
- UBYTE pos;
- DIndex *index;
-
- /*Skip past true-color values*/
- index=(DIndex *)((ULONG)drng+sizeof(DRNG)+4*drng->ntrue);
-
- /*Colors won't cycle if rate is zero, so return 0*/
- if(drng->rate==0)
- return(0);
-
- *rate=16384/drng->rate;
-
- /*If flags==0, there is no color cycling, so return*/
- if(drng->flags==0)
- return(0);
-
- /*Get the color registers to cycle*/
- for(pos=0;pos<drng->nregs;pos++)
- {
- cycleTable[pos]=index->index;
- index=(DIndex *)((ULONG)index+sizeof(DIndex));
- }
-
- /*Return the number of colors that are cycling*/
- return(drng->nregs);
- }
-
- /*Cycle a screen's colors according to the manner specified in cycleTable*/
- void cycleColors(UBYTE *cycleTable,UWORD *colorTable,UBYTE length,
- UBYTE numColors)
- {
- UWORD tempColor;
- BYTE color;
-
- /*Get the first color in the cycle list*/
- tempColor=colorTable[cycleTable[length-1]];
-
- /*Shift each color in the list to its next place in the color table*/
- for(color=length-2;color>=0;color--)
- colorTable[cycleTable[color+1]]=colorTable[cycleTable[color]];
-
- /*The first color in the list became the last color */
- colorTable[cycleTable[0]]=tempColor;
-
-
- LoadRGB4(&(prevScreen->ViewPort),colorTable,numColors);
- }
-
- /*Setup the copper list for dynamic hires images (as output by Macro Paint;*/
- /*Digi-View dynamic hires images aren't supported yet).*/
- void setupDynHires(struct Screen *scr,UWORD *colorBuf)
- {
- UBYTE color;
-
- /*Get the first visible line on the screen*/
- UWORD line=(scr->TopEdge < 0) ? -(scr->TopEdge) : 0;
-
- struct UCopList *cl,*oldCl;
-
- LoadRGB4(&(scr->ViewPort),colorBuf,16);
-
- if(line > 10)
- line-=10;
- else
- line=0;
-
- /*Allocate the copper list header*/
- cl=(struct UCopList *)AllocMem(sizeof(struct UCopList),
- MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
-
- /*Return if there was no memory*/
- if(cl==NULL)
- return;
-
- /*Initialize the number of copper list entries */
- CINIT(cl,17*2*scr->Height);
-
- /*If the image is interlaced, only get the colors for every other*/
- /*scan line (if we were to try to setup every scan line, the image*/
- /*wouldn't come out)*/
- if(scr->ViewPort.Modes & LACE)
- for(;line<scr->Height/2;line++)
- {
- CWAIT(cl,(line-1)<<1,112);
-
- /*Macro Paint only changes colors 4-16*/
- for(color=4;color<16;color++)
- CMOVE(cl,custom.color[color],colorBuf[(line<<5)+color]);
- }
- else
- for(;line<scr->Height;line++)
- {
- CWAIT(cl,(line-1),112)
-
- for(color=4;color<16;color++)
- CMOVE(cl,custom.color[color],colorBuf[(line<<4)+color]);
- }
-
- /*Terminate the copper list*/
- CEND(cl);
-
- /*Install the new copper list, storing the previous one (if any)*/
- oldCl=scr->ViewPort.UCopIns;
- scr->ViewPort.UCopIns=cl;
- RethinkDisplay();
-
- /*If there was a previous copper list, free its memory*/
- if(oldCl!=NULL)
- {
- if(oldCl->FirstCopList != NULL)
- FreeCopList(oldCl->FirstCopList);
- FreeMem(oldCl,sizeof(struct UCopList));
- }
-
- return;
- }
-
- /*Setup the copper list for a SHAM image*/
- void setupSHAM(struct Screen *scr,UWORD *sham)
- {
- int posInBuf=17;
- UBYTE color;
-
- /*Get the first visible line on the screen*/
- UWORD line=(scr->TopEdge < 0) ? -(scr->TopEdge) : 0;
- struct UCopList *cl,*oldCl;
-
- /*Start at a line before the first visible line
- if(line > 10)
- line-=10;
- else
- line=0;
-
- /*Allocate the memory for the copper list header*/
- cl=(struct UCopList *)AllocMem(sizeof(struct UCopList),
- MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
-
- if(cl==NULL)
- return;
-
- /*Skip past the colors for the first line (which are the same */
- /*as the contents of the CMAP chunk*/
- posInBuf+=(16*line);
-
- /*Create the copper list*/
- for(;line<scr->Height;line++)
- {
- CWAIT(cl,line,200)
- for(color=0;color<16;color++)
- CMOVE(cl,custom.color[color],sham[posInBuf++]);
- }
-
- /*Terminate it*/
- CEND(cl);
-
- /*Install it*/
- oldCl=scr->ViewPort.UCopIns;
- scr->ViewPort.UCopIns=cl;
- RethinkDisplay();
-
- /*Free the memory of the old copper list, if one existed*/
- if(oldCl!=NULL)
- {
- if(oldCl->FirstCopList != NULL)
- FreeCopList(oldCl->FirstCopList);
- FreeMem(oldCl,sizeof(struct UCopList));
- }
-
- return;
- }
-
- /*End of Misc.c*/
-