home *** CD-ROM | disk | FTP | other *** search
- /*
- * Amiga Graphics for Window Metafile Reader.
- *
- * $Log: amiga.c,v $
- * Revision 1.9 1995/12/04 19:27:25 JFusco
- * Added interlace flag to OpenScreen().
- * Added debug statements.
- *
- * Revision 1.8 1994/11/09 08:16:51 JFusco
- * Does not print title if file is being saved.
- *
- * Revision 1.7 1994/11/08 22:10:52 JFusco
- * Added iff save.
- *
- * Revision 1.6 1994/06/27 22:40:00 JFusco
- * Reverted to 400x200 window for aspect ratio, which still needs work.
- *
- * Revision 1.5 1994/06/26 18:03:53 JFusco
- * Fixes color matching problems.
- *
- * Revision 1.4 1994/06/25 02:28:03 JFusco
- * Better fills (?). Tries to match luminance of color values.
- *
- * Revision 1.3 1994/06/20 23:22:21 JFusco
- * Now does polygon filling (barely).
- *
- * Revision 1.2 1994/06/19 22:59:55 JFusco
- * Added still more machine dependent stuff.
- *
- * Revision 1.1 1994/06/18 03:09:47 JFusco
- * Initial revision
- *
- */
-
- #include <stdio.h>
- #include <string.h>
- #undef memcmp
- #include <assert.h>
-
- #define INTUI_V36_NAMES_ONLY
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include <graphics/copper.h>
- #include <graphics/display.h>
- #include <graphics/view.h>
- #include <time.h>
-
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
-
- #include "wmf.h"
- extern wmf_hdr_t FileHdr;
- extern char *filename, *savename;
-
- #include "amiga.h"
-
- #define ONE_TIME_WARNING(msg) { static warn=1;\
- if (warn) {warn=0; fprintf(stderr,msg);}}
-
- #ifdef DEBUG
- extern int RecCtr;
- #define DBGREC printf("RecCtr=%d\n",RecCtr)
- #else
- #define DBGREC
- #endif
-
- static unsigned numColors = NUM_COLORS;
- static unsigned ColorsUsed = 1;
- static RGB_color_t ColorTable[NUM_COLORS];
-
- #ifdef LATTICE
- int CXBRK(void) {CleanExit(0);return 0;}
- /* void chkabort(void) {return;} */
- #endif
-
- struct Screen *AmigaScreen = NULL;
- struct Window *AmigaWindow = NULL;
- struct Library *IntuitionBase = NULL, *GfxBase = NULL;
-
- static unsigned char *tmpRasBuf = NULL;
-
- /* Virtual Window (for debug only) */
- extern short Top, Left, Bottom, Right;
-
- /* Local Prototypes. */
- void OpenAmigaLibs();
- void GetCCIR( RGB_color_t *, unsigned long *, long *, long * );
- void OpenAmigaWindow();
- void SetRGBColor( RGB_color_t * );
-
- void OpenAmigaLibs()
- {
- if(!(IntuitionBase = OpenLibrary("intuition.library", 37L))) {
- printf("Could not open intuition.library!\n");
- exit(0);
- }
-
- if(!(GfxBase = OpenLibrary("graphics.library",0))) {
- printf("Could not open graphics.library!\n");
- exit(0);
- };
- }
-
- void CleanAmiga()
- {
- int i;
- #ifdef DEBUG
- printf("ColorsUsed=%d\n",ColorsUsed);
- for(i=0;i<ColorsUsed;i++) {
- printf("%2d r=%02x g=%02x b=%02x\n", i,
- ColorTable[i].Red, ColorTable[i].Green, ColorTable[i].Blue );
- }
- #endif
- if (tmpRasBuf) FreeMem( tmpRasBuf, BITPLANE_SIZE );
- if (AmigaWindow) CloseWindow(AmigaWindow);
- if (AmigaScreen) CloseScreen(AmigaScreen);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (GfxBase) CloseLibrary(GfxBase);
- }
-
- void OpenAmigaWindow()
- {
- unsigned short *areabuffer = NULL;
- static struct AreaInfo area_info;
- static struct TmpRas tmp_ras;
- static UWORD pens[] = { ~0 };
- unsigned i;
-
- OpenAmigaLibs();
-
- AmigaScreen = OpenScreenTags( NULL,
- SA_Width, SCREENX,
- SA_Height, SCREENY,
- SA_Depth, SCREEN_DEPTH,
- SA_Type, CUSTOMSCREEN,
- SA_Pens, (ULONG) pens,
- SA_DisplayID, HIRES_KEY | LACE,
- SA_Title, filename,
- SA_ShowTitle, (ULONG)(savename==NULL),
- TAG_DONE );
- if (!(AmigaScreen)) {
- perror("could not open screen.");
- CleanAmiga();
- exit(1);
- };
-
- AmigaWindow = OpenWindowTags( NULL,
- WA_Left, 10,
- WA_Top, 10,
- WA_Width, WINDOWX,
- WA_Height, WINDOWY,
- WA_Borderless, TRUE,
- WA_Backdrop, TRUE,
- WA_CloseGadget, FALSE,
- WA_SizeGadget, TRUE,
- WA_DragBar, TRUE,
- WA_SmartRefresh, TRUE,
- WA_CustomScreen, AmigaScreen,
- WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS,
- TAG_DONE );
-
- if (!(AmigaWindow)) {
- perror("could not open window.");
- CleanAmiga();
- exit(1);
- };
-
- /* Default the color palette. */
- for (i=0; i<numColors; i++) {
- SetRGB4( &AmigaScreen->ViewPort, i,
- (15-(i*(16/numColors))),
- (15-(i*(16/numColors))),
- (15-(i*(16/numColors))) );
- }
-
- /* Set default value for pens and drawing mode. */
- SetAPen(AmigaWindow->RPort,(numColors-1));
- SetBPen(AmigaWindow->RPort,0);
- SetDrMd(AmigaWindow->RPort,JAM2);
-
- /* Reserve pen 0 for background store 8-bit color regs. */
- ColorTable[0].Type = 0;
- ColorTable[0].Red = 0xff;
- ColorTable[0].Green = 0xff;
- ColorTable[0].Blue = 0xff;
- ColorsUsed = 1;
-
- /* Initialize AreaInfo - this should be way too much space! */
- areabuffer = (unsigned short *) calloc(FileHdr.Largest, sizeof(unsigned short));
- tmpRasBuf = AllocMem( BITPLANE_SIZE, MEMF_CLEAR | MEMF_CHIP );
- assert( tmpRasBuf );
- assert( areabuffer );
- InitArea(&area_info, areabuffer,(FileHdr.Largest*sizeof(short))/5 );
- InitTmpRas(&tmp_ras, tmpRasBuf, BITPLANE_SIZE );
-
- AmigaWindow->RPort->TmpRas = &tmp_ras;
- AmigaWindow->RPort->AreaInfo = &area_info;
- }
-
- MoveAmiga( short x, short y )
- {
- Move( AmigaWindow->RPort, x, y );
- }
-
- DrawAmiga( short x, short y )
- {
- Draw( AmigaWindow->RPort, x, y );
- }
-
- AmigaDelay( unsigned t )
- {
- time_t time1;
-
- time1 = time(NULL);
- while (time(NULL) - time1 < t);
- }
-
- void AmigaWait()
- {
- ULONG signalmask, signals = 0;
-
- signalmask = 1L << AmigaWindow->UserPort->mp_SigBit;
-
- while( !(signals & signalmask) ) {
- signals = Wait(signalmask);
- }
- }
-
- void AmigaSave( char *fname )
- {
- ScreenDump(AmigaScreen, fname);
- }
-
- GetPixelAspect( int *x, int *y )
- {
- /* Needs more, okay for now. */
- if (INTERLACED) {
- *x=1;
- *y=1;
- }
- else {
- *x=1;
- *y=2;
- }
- }
-
- SetDrawingMode( unsigned short mode )
- {
- switch( mode ) {
- case 7:
- DBGREC;
- SetDrMd(AmigaWindow->RPort, JAM2 );
- fprintf(stderr,"XOR drawing\n");
- break;
- case 13:
- SetDrMd(AmigaWindow->RPort, JAM2 | INVERSVID);
- break;
- default:
- DBGREC;
- fprintf(stderr,"Unimplemented Drawing Mode %04hx\n", mode);
- SetDrMd(AmigaWindow->RPort, JAM2 | INVERSVID);
- break;
- };
- }
-
- PolygonMoveAmiga( short x, short y )
- {
- AreaMove( AmigaWindow->RPort, x, y );
- }
-
- PolygonDrawAmiga( short x, short y )
- {
- AreaDraw( AmigaWindow->RPort, x, y );
- }
-
- PolygonEndAmiga()
- {
- if (AreaEnd( AmigaWindow->RPort ))
- {
- DBGREC;
- fprintf(stderr,"Invalid area\n");
- }
- }
-
- SetBrushStyleAmiga( brush_t *Brush )
- {
- SetRGBColor( &Brush->Color.RGB );
- switch (Brush->Style) {
- case 0: /* Solid */
- SetDrMd(AmigaWindow->RPort,JAM2);
- break;
- case 1: /* Hollow */
- SetDrMd(AmigaWindow->RPort,JAM2|COMPLEMENT);
- break;
- case 2:
- ONE_TIME_WARNING("Cross hatched brush not supported\n");
- break;
- default:
- ONE_TIME_WARNING("Unknown brush type.\n");
- break;
- }
- }
-
- SetPenStyleAmiga( pen_t *Pen )
- {
- static int warnings=0;
- unsigned short pattern;
-
- if (Pen->Width>1) {
- ONE_TIME_WARNING("Only pen width of 1 supported.\n");
- }
-
- switch( Pen->Style ) {
- case 0:
- pattern = 0xffff; /* Solid */
- break;
- case 1:
- pattern = 0xcccc; /* Dashed */
- break;
- case 2:
- pattern = 0xaaaa; /* Dotted */
- break;
- case 3:
- pattern = 0xd6b5; /* Alternating Dot and Dash */
- break;
- case 4:
- pattern = 0xb5ad; /* Alternating Dash and two Dots */
- break;
- case 5:
- pattern = 0xffff; /* None ? */
- break;
- case 6:
- /* Inside Frame. */
- DBGREC;
- fprintf(stderr,"Inside frame pen type is unimplemented.\n");
- break;
- default:
- DBGREC;
- fprintf(stderr,"Unrecognized pen style %hd assuming solid.\n",Pen->Style);
- pattern = 0xffff;
- break;
- }
- SetRGBColor( &Pen->Color.RGB );
- }
-
- void SetRGBColor( RGB_color_t *Color )
- {
- unsigned long lum, mlum;
- long Cb, Cr, best, mCb, mCr, match, bestdiff;
- unsigned idx, idx_match;
-
- if (Color->Type != 1) {
-
- /* Set to zero for memcmp. */
- Color->Type = 0;
-
- /* Check to see if it's already in the color table. */
- for( idx=0; idx<ColorsUsed; idx++) {
-
- if (memcmp( &ColorTable[idx],
- Color, sizeof(RGB_color_t)) == 0 ) break;
- }
-
- if (ColorsUsed && idx < ColorsUsed) {
-
- /* It's already in the color table. */
- SetAPen(AmigaWindow->RPort,idx);
- }
-
- else if ( ColorsUsed != numColors ) {
-
- /* Not in the color table, but there's room for a new entry. */
- assert( ColorsUsed < numColors );
- memcpy( &ColorTable[ColorsUsed],
- Color, sizeof(RGB_color_t));
- ColorTable[ColorsUsed].Type = 0;
- SetRGB4( &AmigaScreen->ViewPort,
- ColorsUsed,
- (ColorTable[ColorsUsed].Red >> 4),
- (ColorTable[ColorsUsed].Green >> 4),
- (ColorTable[ColorsUsed].Blue >> 4) );
- SetAPen(AmigaWindow->RPort,ColorsUsed);
- ColorsUsed++;
- }
-
- else {
-
- /* Not in the table and there's no more room. */
- /* Get the closest match. */
- ONE_TIME_WARNING("Too many colors, will find closest match.\n");
- GetCCIR( Color, &lum, &Cb, &Cr );
-
- for( idx=0; idx<ColorsUsed; idx++) {
-
- GetCCIR( &ColorTable[idx], &mlum, &mCb, &mCr );
-
- /* Compare the dot product of the two color 'vectors' */
- match = lum * mlum + Cb * mCb + Cr * mCr;
-
- if (idx==0) {
- idx_match = 0;
- bestdiff = abs(match);
- best = match;
- }
-
- /* Take our best match and compare the difference. */
- else if (bestdiff > abs(match-best)) {
- idx_match = idx;
- bestdiff = abs(match-best);
- best = match;
- }
- }
- SetAPen(AmigaWindow->RPort,idx_match);
- }
- SetBPen(AmigaWindow->RPort,0);
- }
- else {
- Indexed_color_t *lu = (Indexed_color_t *)Color;
- if (lu->Index < ColorsUsed) {
- fprintf(stderr,"Using color index\n");
- SetAPen(AmigaWindow->RPort,lu->Index);
- }
- else {
- DBGREC;
- fprintf(stderr,"Color index out of range (not supported)\n");
- }
- }
- }
-
- /* Make a color vector. */
- void GetCCIR( RGB_color_t *Color, unsigned long *lum,
- long *Cb, long *Cr )
- {
- *lum = Color->Red * 30
- + Color->Green * 59
- + Color->Blue * 11;
-
- *Cb = Color->Red * 17
- - Color->Green * 33
- + Color->Blue * 50;
-
- *Cr = Color->Red * 50
- - Color->Green * 42
- - Color->Blue * 8;
-
- *lum /= 100;
- *Cb /= 100;
- *Cr /= 100;
- }
-