1 /* Modified version for AROS - The AROS Research OS
8 #include <exec/types.h>
9 #include <dos/rdargs.h>
10 /* #include <devices/printer.h>
11 #include <devices/prtgfx.h> */
12 #include <intuition/screens.h>
13 #include <intuition/intuition.h>
14 #include <exec/memory.h>
17 #include <graphics/gfxmacros.h>
18 #include <graphics/copper.h>
19 #include <hardware/custom.h>
26 #include <proto/exec.h>
27 #include <proto/intuition.h>
28 #include <proto/graphics.h>
29 #include <proto/iffparse.h>
30 #include <proto/dos.h>
31 #include <proto/alib.h>
33 BPTR StdErr
=BNULL
; /*'Standard error' for AmigaDOS IO functions*/
35 /*These are defined in 2View.c, but this file needs to reference them*/
37 extern struct NewScreen newScreen
;
38 extern struct NewWindow newWindow
;
40 extern struct IFFHandle
*iff
; /*IFF handle*/
41 extern BPTR pL
; /*Playlist file pointer*/
42 extern BOOL masking
,print
,toFront
,printPics
;
44 /*A true here indicates the current ILBM file is compressed*/
45 extern BYTE Compression
;
47 extern char trashBuf
[512]; /* A place to dump mask information */
49 extern struct Screen
*screen
;
50 extern struct Window
*window
;
52 /*The previous screen and window*/
53 extern struct Window
*prevWindow
;
54 extern struct Screen
*prevScreen
;
56 /*Libraries we'll need*/
57 extern struct Library
*IFFParseBase
;
58 /* extern struct Library *IntuitionBase; */
59 extern struct GfxBase
*GfxBase
;
61 /*Provided by the compiler*/
62 /* extern struct Library *SysBase;
63 extern struct Library *DOSBase; */
66 extern UBYTE numColors
;
68 extern UWORD destMap
[32];
70 extern struct Custom custom
;
72 /*Convert the CMAP information into a color map, then set the colors*/
73 /*of the screen according to that colormap*/
74 void setScreenColors(struct Screen
*scr
, UBYTE
*colorMap
, UBYTE depth
,
75 UWORD
*destColorMap
,UBYTE
*colors
)
79 numColors
=1<<depth
; /*Get the number of colors (generally 2^depth)*/
81 if(newScreen
.ViewModes
& HAM
) /*There are, of course, 2 exceptions*/
83 if(newScreen
.ViewModes
& EXTRA_HALFBRITE
)
86 /*For each color, convert it from CMAP to Amiga form and*/
87 /*store it (both in an unchanging table (colorTable) and in a "work" */
88 /*table (destColorMap), where the values are free to change during */
89 /*color cycling, etc.*/
90 for(i
=0;i
<numColors
;i
++)
91 colorTable
[i
]=destColorMap
[i
]=
92 (15 & (colorMap
[i
*3])>>4)<<8 | (15 & (colorMap
[i
*3+1])>>4)<<4 |
93 (15 & (colorMap
[i
*3+2]>>4));
95 /*Store the color table*/
96 LoadRGB4(&(scr
->ViewPort
),destColorMap
,numColors
);
98 /*Return the number of colors*/
104 #define GetWord(ptr) ((ptr[0] << 8) + ptr[1])
106 /*Make a newScreen structure using the BMHD chunk*/
107 void getBMHD(UBYTE
* ptr
)
109 struct BitMapHeader bmhd
;
111 bmhd
.w
= GetWord(ptr
); ptr
+= 2;
112 bmhd
.h
= GetWord(ptr
); ptr
+= 2;
113 bmhd
.x
= GetWord(ptr
); ptr
+= 2;
114 bmhd
.y
= GetWord(ptr
); ptr
+= 2;
115 bmhd
.nplanes
= *ptr
++;
116 bmhd
.Masking
= *ptr
++;
117 bmhd
.Compression
= *ptr
++;
119 bmhd
.TransparentColor
= *ptr
++;
120 bmhd
.XAspect
= *ptr
++;
121 bmhd
.YAspect
= *ptr
++;
122 bmhd
.PageWidth
= GetWord(ptr
); ptr
+= 2;
123 bmhd
.PageHeight
= GetWord(ptr
);
125 /*Define the screen as hires if*/
126 if(bmhd
.PageWidth
> 400 && bmhd
.PageWidth
<=704 && bmhd
.nplanes
< 5)
127 newScreen
.ViewModes
|=HIRES
; /*wider than 400 pixels and not */
128 /*deeper than 4 bitplanes*/
130 if(bmhd
.PageHeight
> 300 && bmhd
.PageHeight
<=512) /*Define the screen as interlaced*/
131 newScreen
.ViewModes
|=LACE
; /*if the height is > 300 pixels*/
133 newScreen
.Width
=bmhd
.w
; /*Store the rest of the values*/
134 newScreen
.Height
=bmhd
.h
;
136 newScreen
.LeftEdge
=bmhd
.x
;
137 newScreen
.TopEdge
=bmhd
.y
;
138 newScreen
.Depth
=bmhd
.nplanes
;
140 masking
=(bmhd
.Masking
== 1);
142 Compression
=(bmhd
.Compression
!=0); /*Compression flag. Store for*/
147 /*Data structures for ReadArgs()*/
154 "FILE/A/M,SECS=SECONDS/K/N,TICKS/K/N,LOOP/S,FROM/K,PRINT/S"
157 /*Parse the argument list, using ReadArgs()*/
158 void ParseArgs(IPTR
*args
)
160 ReadArgs("FILE/A/M,SECS=SECONDS/K/N,TICKS/K/N,LOOP/S,FROM/K,PRINT/S",
165 /*Check to see which mouse buttons have been pressed*/
166 ButtonTypes
checkButton(void)
168 struct IntuiMessage
*mesg
;
169 ButtonTypes Button
=none
;
170 static int justActivated
=FALSE
;
172 /*This function disregards a select (left) mouse button click*/
173 /*if the window's just been activated. This is so that a user*/
174 /*can click on another window, then make this one active again,*/
175 /*without advancing to the next picture*/
177 /*While there are messages to be read...*/
178 while((mesg
=(struct IntuiMessage
*)GetMsg(prevWindow
->UserPort
))!=NULL
)
183 case IDCMP_ACTIVEWINDOW
: /*Set the appropriate flag if the window*/
184 justActivated
=TRUE
; /*was just activated*/
186 case IDCMP_VANILLAKEY
:
189 case 16: /*CTRL-P - Print (if this picture hasn't been*/
190 if(print
) /*printed; this is designed in case the user*/
191 { /*holds down CTRL-P: we don't want 10-20 */
192 /*print requests to get queued up */
193 dumpRastPort(&(prevScreen
->RastPort
),
194 &(prevScreen
->ViewPort
));
198 case 4: /*CTRL-D - Abort everything*/
202 Button
=select
; /*CTRL-C - Advance to next picture*/
204 case 9: /*TAB: Switch color cycling on/off*/
210 case IDCMP_MOUSEBUTTONS
: /*Interpret a button click*/
211 if(mesg
->Code
==SELECTDOWN
) /*If the left button was pushed,*/
213 if(justActivated
) /*and not so as to activate the*/
214 { /*window, advance to the next*/
215 justActivated
=FALSE
; /*screen*/
220 } else if(mesg
->Code
== MENUDOWN
) /*If the right button was*/
221 Button
=menu
; /*pushed, we'll want to*/
224 ReplyMsg((struct Message
*)mesg
); /*Reply to the message*/
226 return(Button
); /*Return the results*/
229 /*Toggle color cycling on and off*/
230 void toggleCycling(void)
234 cycle
=(cycle
) ? FALSE
: TRUE
; /*Toggle the color cycling lag*/
235 LoadRGB4(&(prevScreen
->ViewPort
),colorTable
,numColors
);
236 for(c
=0;c
<numColors
;c
++)
237 destMap
[c
]=colorTable
[c
];
241 struct EasyStruct erError2Line
=
243 sizeof(struct EasyStruct
),
245 "Program error: 2View",
250 struct EasyStruct erError1Line
=
252 sizeof(struct EasyStruct
),
254 "Program error: 2View",
259 /*This prints an error to the console, if we were run from the CLI*/
260 /*This is done instead of using Output() so as to get around any redirection*/
261 /*that may be in place (just like the standard C stderr)*/
262 /*If we can't open a StdErr or 2View was run from Workbench, a requester */
264 void printError(char *fmt
,...)
271 vsnprintf (error
, sizeof(error
), fmt
, args
);
276 StdErr
=Open("CONSOLE:",MODE_OLDFILE
);
278 /* If we can't open StdErr, or Output()==BNULL (meaning we're running */
279 /* Workbench), put up a requester */
280 if(StdErr
==BNULL
|| Output()==BNULL
)
282 EasyRequest(NULL
,&erError1Line
,NULL
,(IPTR
)error
,(IPTR
)"Exiting...");
287 FPuts(StdErr
,"\nExiting\n");
292 /*Free allocated resources in anticipation of quitting*/
296 /*Close the ARexx port*/
300 /*Close the standard-error file if opened*/
304 /*Close a previous screen and window, if open*/
306 CloseWindow(prevWindow
);
308 CloseScreen(prevScreen
);
310 /*Close a current screen and window, if open*/
322 if(IFFParseBase
!=NULL
)
323 CloseLibrary(IFFParseBase
);
325 if(IntuitionBase
!=NULL
)
326 CloseLibrary((struct Library
*)IntuitionBase
);
329 CloseLibrary((struct Library
*)GfxBase
);
332 /*Print the specified RastPort (whose ViewPort is pointed to by vp*/
333 BOOL
dumpRastPort(struct RastPort
*rp
,struct ViewPort
*vp
)
336 struct IODRPReq
*printerMsg
;
337 struct MsgPort
*printerPort
;
338 static BOOL ableToPrint
=TRUE
;
343 printerPort
=CreatePort("2View.print.port",0);
344 if(printerPort
!=NULL
)
346 printerMsg
=(struct IORequest
*)CreateExtIO(printerPort
,
347 (long)sizeof(struct IODRPReq
));
349 if(printerMsg
!= NULL
)
351 /*Open the printer device*/
352 if(OpenDevice("printer.device",0,printerMsg
,0)==0)
354 /*Set up the IODRPReq structure*/
355 printerMsg
->io_Command
=PRD_DUMPRPORT
;
356 printerMsg
->io_RastPort
=rp
;
357 printerMsg
->io_ColorMap
=vp
->ColorMap
;
358 printerMsg
->io_Modes
=vp
->Modes
;
359 printerMsg
->io_SrcX
=0;
360 printerMsg
->io_SrcY
=0;
361 printerMsg
->io_SrcWidth
=vp
->DWidth
;
362 printerMsg
->io_SrcHeight
=vp
->DHeight
;
363 printerMsg
->io_Special
=SPECIAL_ASPECT
|SPECIAL_FULLROWS
|
367 if(DoIO(printerMsg
)==0)
370 CloseDevice(printerMsg
);
372 DeleteExtIO(printerMsg
);
374 DeletePort(printerPort
);
384 /*Determine which colors to cycle, for a CRNG*/
385 UBYTE
interpretCRNG(UBYTE
*cycleTable
,CRNG
*crng
,UBYTE
*rate
)
390 /*If the rate is zero, colors won't cycle anyway, so return 0*/
394 /*Get the cycle rate*/
395 *rate
=16384/crng
->rate
;
397 /*If the colors are actually suppossed to be cycling...*/
400 /*Get the number of colors to cycle*/
401 length
=crng
->high
-crng
->low
+1;
403 /*If there are colors to cycle*/
408 for(pos
=0,color
=crng
->low
;pos
<length
;pos
++,color
++)
409 cycleTable
[pos
]=color
;
412 for(pos
=0,color
=crng
->high
;pos
<length
;pos
++,color
--)
413 cycleTable
[pos
]=color
;
419 UBYTE
interpretDRNG(UBYTE
*cycleTable
,DRNG
*drng
,UBYTE
*rate
)
424 /*Skip past true-color values*/
425 index
=(DIndex
*)((IPTR
)drng
+sizeof(DRNG
)+4*drng
->ntrue
);
427 /*Colors won't cycle if rate is zero, so return 0*/
431 *rate
=16384/drng
->rate
;
433 /*If flags==0, there is no color cycling, so return*/
437 /*Get the color registers to cycle*/
438 for(pos
=0;pos
<drng
->nregs
;pos
++)
440 cycleTable
[pos
]=index
->index
;
441 index
=(DIndex
*)((IPTR
)index
+sizeof(DIndex
));
444 /*Return the number of colors that are cycling*/
448 /*Cycle a screen's colors according to the manner specified in cycleTable*/
449 void cycleColors(UBYTE
*cycleTable
,UWORD
*colorTable
,UBYTE length
,
455 /*Get the first color in the cycle list*/
456 tempColor
=colorTable
[cycleTable
[length
-1]];
458 /*Shift each color in the list to its next place in the color table*/
459 for(color
=length
-2;color
>=0;color
--)
460 colorTable
[cycleTable
[color
+1]]=colorTable
[cycleTable
[color
]];
462 /*The first color in the list became the last color */
463 colorTable
[cycleTable
[0]]=tempColor
;
465 LoadRGB4(&(prevScreen
->ViewPort
),colorTable
,numColors
);
469 /*Setup the copper list for dynamic hires images (as output by Macro Paint;*/
470 /*Digi-View dynamic hires images aren't supported yet).*/
471 void setupDynHires(struct Screen
*scr
,UWORD
*colorBuf
)
475 /*Get the first visible line on the screen*/
476 UWORD line
=(scr
->TopEdge
< 0) ? -(scr
->TopEdge
) : 0;
478 struct UCopList
*cl
,*oldCl
;
480 LoadRGB4(&(scr
->ViewPort
),colorBuf
,16);
487 /*Allocate the copper list header*/
488 cl
=(struct UCopList
*)AllocMem(sizeof(struct UCopList
),
489 MEMF_PUBLIC
|MEMF_CHIP
|MEMF_CLEAR
);
491 /*Return if there was no memory*/
495 /*Initialize the number of copper list entries */
496 CINIT(cl
,17*2*scr
->Height
);
498 /*If the image is interlaced, only get the colors for every other*/
499 /*scan line (if we were to try to setup every scan line, the image*/
500 /*wouldn't come out)*/
501 if(scr
->ViewPort
.Modes
& LACE
)
502 for(;line
<scr
->Height
/2;line
++)
504 CWAIT(cl
,(line
-1)<<1,112);
506 /*Macro Paint only changes colors 4-16*/
507 for(color
=4;color
<16;color
++)
508 CMOVE(cl
,custom
.color
[color
],colorBuf
[(line
<<5)+color
]);
511 for(;line
<scr
->Height
;line
++)
513 CWAIT(cl
,(line
-1),112);
515 for(color
=4;color
<16;color
++)
516 CMOVE(cl
,custom
.color
[color
],colorBuf
[(line
<<4)+color
]);
519 /*Terminate the copper list*/
522 /*Install the new copper list, storing the previous one (if any)*/
523 oldCl
=scr
->ViewPort
.UCopIns
;
524 scr
->ViewPort
.UCopIns
=cl
;
527 /*If there was a previous copper list, free its memory*/
530 if(oldCl
->FirstCopList
!= NULL
)
531 FreeCopList(oldCl
->FirstCopList
);
532 FreeMem(oldCl
,sizeof(struct UCopList
));
538 /*Setup the copper list for a SHAM image*/
539 void setupSHAM(struct Screen
*scr
,UWORD
*sham
)
544 /*Get the first visible line on the screen*/
545 UWORD line
=(scr
->TopEdge
< 0) ? -(scr
->TopEdge
) : 0;
546 struct UCopList
*cl
,*oldCl
;
548 /*Start at a line before the first visible line */
554 /*Allocate the memory for the copper list header*/
555 cl
=(struct UCopList
*)AllocMem(sizeof(struct UCopList
),
556 MEMF_PUBLIC
|MEMF_CHIP
|MEMF_CLEAR
);
561 /*Skip past the colors for the first line (which are the same */
562 /*as the contents of the CMAP chunk*/
565 /*Create the copper list*/
566 for(;line
<scr
->Height
;line
++)
569 for(color
=0;color
<16;color
++)
570 CMOVE(cl
,custom
.color
[color
],sham
[posInBuf
++]);
577 oldCl
=scr
->ViewPort
.UCopIns
;
578 scr
->ViewPort
.UCopIns
=cl
;
581 /*Free the memory of the old copper list, if one existed*/
584 if(oldCl
->FirstCopList
!= NULL
)
585 FreeCopList(oldCl
->FirstCopList
);
586 FreeMem(oldCl
,sizeof(struct UCopList
));