/* cybergraphics saver - (C) Vision Factor Development 1994 31/12/94

   Saver for Photogenics
   Photogenics © Almathera 1994, All Rights Reserved

REQUIRES: SAS C V6.50 or higher.

*/

	#include <exec/types.h>
	#include <clib/exec_protos.h>
	#include <dos/dos.h>
	#include <pragmas/exec_pragmas.h>
	#include <cybergraphics/cybergraphics.h>
	#include <intuition/intuition.h>
	#include <pragmas/intuition_pragmas.h>
	#include <pragmas/cybergraphics_pragmas.h>
	#include <proto/exec.h>
	#include <proto/intuition.h>
	#include <proto/graphics.h>
	#include <proto/cybergraphics.h>
	#include "pgs_protos.h"
	#include "pgs_pragmas.h"
	#include "gio.h"

struct	TagItem CModeTags[]=
	{
	 CYBRMREQ_Screen,0,
	 CYBRMREQ_MinDepth,15,
	 CYBRMREQ_MaxDepth,32,
	 CYBRMREQ_WinTitle,(ULONG)"Select CyBERgraphics ScreenMode",
	 CYBRMREQ_OKText,(ULONG)"OK",
	 CYBRMREQ_CancelText,(ULONG)"Cancel",
	 TAG_DONE
	};


struct Library *CyberGfxBase;

/* prototypes */
__asm ULONG __saveds GioInfo(void);
__asm ULONG __saveds GioExamine(register __a0 struct GIOData *giodata);
__asm ULONG __saveds GioRead(register __a0 struct GIOData *giodata);
__asm ULONG __saveds GioWrite(register __a0 struct GIOData *giodata);
/* end of prototypes */


__asm ULONG __saveds GioInfo(void)
{
	return(GIOF_SAVER24);
}

__asm ULONG __saveds GioExamine(register __a0 struct GIOData *giodata)
{
 return(0L);
}

#define DOSBase giodata->DOSBase
#define PgsBase giodata->PgsBase
#define IntuitionBase giodata->IntuitionBase

__asm ULONG __saveds GioRead(register __a0 struct GIOData *giodata)
{
 return(0L);
}

WriteRect(struct GIOData *giodata,UWORD SrcX,UWORD SrcY,UWORD SrcMod,struct RastPort *rp,UWORD DestX,UWORD DestY,UWORD SizeX,UWORD SizeY);

WriteRect(struct GIOData *giodata,UWORD SrcX,UWORD SrcY,UWORD SrcMod,struct RastPort *rp,UWORD DestX,UWORD DestY,UWORD SizeX,UWORD SizeY)
{
 int i,j;
 UBYTE *peeker;

 for(i=0;i<SizeY;i++)
 {
	peeker=GetLine(giodata,i+SrcY);
	WritePixelArray(peeker,SrcX,0,SizeX*3,rp,DestX,DestY+i,SizeX,1,RECTFMT_RGB);
	ReleaseLine(giodata,i+SrcY);
 };
}

__asm ULONG __saveds GioWrite(register __a0 struct GIOData *giodata)
{
	if (giodata->Depth == 24)
	{
	 int ScrWidth,ScrHeight,OffX=0,OffY=0,DispWidth,DispHeight;

	if(CyberGfxBase=OpenLibrary("cybergraphics.library",40))
	{
	 struct Screen *Scr,*PScr;
	 struct RastPort *rp;
	 struct BitMap *bm;
	 long	depth;
	 int Width,Height;
	 ULONG	ModeID;

	 PScr=(ULONG)giodata->PgsScreen;
	 ModeID=GetVPModeID(&PScr->ViewPort);
	 if(IsCyberModeID(ModeID))
	 {
	  depth=GetCyberIDAttr(CYBRIDATTR_DEPTH,ModeID);
	 }
	 else
	 {
          depth=8;
	 }

	if(depth <= 8)
	{
	 CModeTags[0].ti_Data=PScr;
	 ModeID=CModeRequestTagList(0L,CModeTags);

	 Width = giodata->Width; Height = giodata->Height;

	 if(Scr=(struct Screen *)OpenScreenTags(0L,SA_DisplayID,ModeID,
						   SA_ShowTitle,0,
						   SA_Title,0,
						   SA_Quiet,1,
						   SA_AutoScroll,1,
						   SA_Overscan,1,
						   SA_Depth,8,
						   TAG_DONE))
	 {
	  struct Window *Wnd;
	  ShowTitle(Scr,0L); // We don't want a title bar !
	  ScrWidth=Scr->Width; ScrHeight=Scr->Height;
	  if(Wnd=(struct Window *)OpenWindowTags(0L,WA_Activate,1,
						    WA_CustomScreen,Scr,
						    WA_Width,Scr->Width,
						    WA_Height,Scr->Height,
						    WA_Borderless,1,
						    WA_Backdrop,1,
						    WA_Title,0,
						    WA_Flags,WFLG_RMBTRAP,
						    WA_IDCMP,IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS,
						    TAG_DONE))
	  {
	   struct IntuiMessage *imsg;
	   BOOL end=FALSE,UpdateDis=TRUE;


 	   DispWidth=ScrWidth; if(Width < ScrWidth) DispWidth = Width;
	   DispHeight=ScrHeight; if(Height < ScrHeight) DispHeight = Height;

	   while(!end)
	   {
	    if(UpdateDis)
	    {
		WriteRect(giodata,OffX,OffY,Width,Wnd->RPort,Wnd->BorderLeft,Wnd->BorderTop,DispWidth,DispHeight);
	     };
	    UpdateDis=FALSE;

	   WaitPort(Wnd->UserPort);

	   while(imsg=(struct IntuiMessage *)GetMsg(Wnd->UserPort))
	   {
	    ULONG IClass=imsg->Class;
	    UWORD IQual=imsg->Qualifier;
	    UWORD ICode=imsg->Code;
	    UWORD StepX,StepY;
	 
	    switch(IClass)
	    {
	     case MOUSEBUTTONS:	switch(ICode)
				{
				 case	IECODE_LBUTTON:
					end=TRUE;
					break;
				}
				break;
	     case RAWKEY:
		if(IQual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
				{
				 StepX=StepY=1;
				}
				else
				{
				 StepX=50;
				 StepY=50;
				};

				switch(ICode)
				{
				 case CURSORUP: // CSUP
					if(OffY!=0)
					{
					 OffY-=StepY;
					 if(OffY < 0)
					 {
					  StepY+=OffY;
					  OffY=0;
					 }
					 if(StepY != 0)
					 {
					  MovePixelArray(0,0,&Scr->RastPort,0,StepY,DispWidth,DispHeight-StepY);
					  WriteRect(giodata,OffX,OffY,Width,&Scr->RastPort,Wnd->BorderLeft,Wnd->BorderTop,DispWidth,StepY);
					 }
					};
					break;
				 case CURSORDOWN: // CSDN
					if(Height > DispHeight)
					{
					OffY+=StepY;
					if(OffY > Height-DispHeight)
					{
					 StepY-=(OffY - (Height - DispHeight));
					 OffY=Height-DispHeight;
					 if(OffY < 0) OffY=0;
					};
					 if(StepY != 0)
					 {
					  MovePixelArray(0,StepY,&Scr->RastPort,0,0,DispWidth,DispHeight-StepY);
					  WriteRect(giodata,OffX,OffY+DispHeight-StepY,Width,Wnd->RPort,Wnd->BorderLeft,Wnd->BorderTop+DispHeight-StepY,DispWidth,StepY);
					 }
					};
					break;
				 case CURSORRIGHT: // CSRT
					if(Width > DispWidth)
					{
					OffX+=StepX;
					if(OffX > Width-DispWidth)
					{
					 StepX-=(OffX - (Width - DispWidth));
					 OffX=Width-DispWidth;
					 if(OffX < 0) OffX=0;
					};
					 if(StepX != 0)
					 {
					  MovePixelArray(StepX,0,&Scr->RastPort,0,0,DispWidth-StepX,DispHeight);
					  WriteRect(giodata,OffX+DispWidth-StepX,OffY,Width,Wnd->RPort,Wnd->BorderLeft+DispWidth-StepX,Wnd->BorderTop,StepX,DispHeight);
					 }
					};
					break;
				 case CURSORLEFT: // CSLT
					if(OffX!=0)
					{
					 OffX-=StepX;
					 if(OffX < 0)
					 {
					  StepX+=OffX;
					  OffX=0;
					 }
					 if(StepX != 0)
					 {
					  MovePixelArray(0,0,&Scr->RastPort,StepX,0,DispWidth-StepX,DispHeight);
					  WriteRect(giodata,OffX,OffY,Width,Wnd->RPort,Wnd->BorderLeft,Wnd->BorderTop,StepX,DispHeight);
					 }
					};
					break;
				}
				break;
	  } // end of switch
	 } // end of while 
        } // end of while(!end)
       CloseWindow(Wnd);
       } // end of OpenWindow
       else giodata->Error = LOAD_RAMERR;
       CloseScreen(Scr);
      } // end of OpenScreen
      else giodata->Error = LOAD_RAMERR;

	}
	else
	{
	  struct Window *Wnd;
	  int WndWidth,WndHeight;
	  ScrWidth=PScr->Width; ScrHeight=PScr->Height;
	  WndWidth=ScrWidth; WndHeight=ScrHeight;
	 Width = giodata->Width; Height = giodata->Height;
	  if(Width < ScrWidth) WndWidth=Width;
	  if(Height < ScrWidth) WndHeight=Height;

	  if(Wnd=(struct Window *)OpenWindowTags(0L,WA_Activate,1,
						    WA_CustomScreen,PScr,
						    WA_Width,WndWidth,
						    WA_Height,WndHeight,
						    WA_SmartRefresh,1,
						    WA_DepthGadget,1,
						    WA_SizeGadget,1,
						    WA_DragBar,1,
						    WA_CloseGadget,1,
						    WA_MaxWidth,Width,WA_MaxHeight,Height,
						    WA_MinWidth,200,WA_MinHeight,40,
						    WA_Title,"CyberGraphics Render Window",
						    WA_Flags,WFLG_ACTIVATE,
						    WA_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE,
						    TAG_DONE))
	  {
	   struct IntuiMessage *imsg;
	   BOOL end=FALSE,UpdateDis=TRUE;
		rp=Wnd->RPort;

	   WndWidth=Wnd->Width-Wnd->BorderLeft-Wnd->BorderRight;
	   WndHeight=Wnd->Height-Wnd->BorderTop-Wnd->BorderBottom;
 	   DispWidth=WndWidth; if(Width < WndWidth) DispWidth = Width;
	   DispHeight=WndHeight; if(Height < WndHeight) DispHeight = Height;

	   while(!end)
	   {
	    if(UpdateDis)
	    {
		WriteRect(giodata,OffX,OffY,Width,Wnd->RPort,Wnd->BorderLeft,Wnd->BorderTop,DispWidth,DispHeight);
	     };
	    UpdateDis=FALSE;

	   WaitPort(Wnd->UserPort);

	   while(imsg=(struct IntuiMessage *)GetMsg(Wnd->UserPort))
	   {
	    ULONG IClass=imsg->Class;
	    UWORD IQual=imsg->Qualifier;
	    UWORD ICode=imsg->Code;
	    UWORD StepX,StepY;
	 
	    switch(IClass)
	    {
	     case IDCMP_CLOSEWINDOW:	end=TRUE;
					break;
	     case IDCMP_NEWSIZE:

	   WndWidth=Wnd->Width-Wnd->BorderLeft-Wnd->BorderRight;
	   WndHeight=Wnd->Height-Wnd->BorderTop-Wnd->BorderBottom;
 	   DispWidth=WndWidth; if(Width < WndWidth) DispWidth = Width;
	   DispHeight=WndHeight; if(Height < WndHeight) DispHeight = Height;

					WriteRect(giodata,OffX,OffY,Width,Wnd->RPort,Wnd->BorderLeft,Wnd->BorderTop,DispWidth,DispHeight);
					break;
	     case IDCMP_RAWKEY:
		if(IQual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
				{
				 StepX=StepY=1;
				}
				else
				{
				 StepX=50;
				 StepY=50;
				};

				switch(ICode)
				{
				 case CURSORUP: // CSUP
					if(OffY!=0)
					{
					 OffY-=StepY;
					 if(OffY < 0)
					 {
					  StepY+=OffY;
					  OffY=0;
					 }
					 if(StepY != 0)
					 {
//					  MovePixelArray(0,0,&Scr->RastPort,0,StepY,DispWidth,DispHeight-StepY);
					  WriteRect(giodata,OffX,OffY,Width,Wnd->RPort,Wnd->BorderLeft,Wnd->BorderTop,DispWidth,StepY);
					 }
					};
					break;
				 case CURSORDOWN: // CSDN
					if(Height > DispHeight)
					{
					OffY+=StepY;
					if(OffY > Height-DispHeight)
					{
					 StepY-=(OffY - (Height - DispHeight));
					 OffY=Height-DispHeight;
					 if(OffY < 0) OffY=0;
					};
					 if(StepY != 0)
					 {
//					  MovePixelArray(0,StepY,&Scr->RastPort,0,0,DispWidth,DispHeight-StepY);
					  WriteRect(giodata,OffX,OffY+DispHeight-StepY,Width,Wnd->RPort,Wnd->BorderLeft,Wnd->BorderTop+DispHeight-StepY,DispWidth,StepY);
					 }
					};
					break;
				 case CURSORRIGHT: // CSRT
					if(Width > DispWidth)
					{
					OffX+=StepX;
					if(OffX > Width-DispWidth)
					{
					 StepX-=(OffX - (Width - DispWidth));
					 OffX=Width-DispWidth;
					 if(OffX < 0) OffX=0;
					};
					 if(StepX != 0)
					 {
//					  MovePixelArray(StepX,0,&Scr->RastPort,0,0,DispWidth-StepX,DispHeight);
					  WriteRect(giodata,OffX+DispWidth-StepX,OffY,Width,Wnd->RPort,Wnd->BorderLeft+DispWidth-StepX,Wnd->BorderTop,StepX,DispHeight);
					 }
					};
					break;
				 case CURSORLEFT: // CSLT
					if(OffX!=0)
					{
					 OffX-=StepX;
					 if(OffX < 0)
					 {
					  StepX+=OffX;
					  OffX=0;
					 }
					 if(StepX != 0)
					 {
//					  MovePixelArray(0,0,&Scr->RastPort,StepX,0,DispWidth-StepX,DispHeight);
					  WriteRect(giodata,OffX,OffY,Width,Wnd->RPort,Wnd->BorderLeft,Wnd->BorderTop,StepX,DispHeight);
					 }
					};
					break;
				}
				break;
	  } // end of switch
	 } // end of while 
        } // end of while(!end)
       CloseWindow(Wnd);
       } // end of OpenWindow
       else giodata->Error = LOAD_RAMERR;

	}

      CloseLibrary(CyberGfxBase);
     }
     else giodata->Error = LOAD_SYSERR;
    }
    else
    {
     giodata->Error = LOAD_WRONGTYPE;
    }
 return(0L);
}

	
