/** dbf.c ******************************************************************* * * Intuition integrated doubly buffered display routines. * * Written by Olaf `Olsen' Barthel, 16-Sep-1991 * ***************************************************************************/ #include #include #include #include #include #include #include #include extern struct BitMap * __regargs CreateBitMap(BYTE Depth,UWORD Width,UWORD Height); extern VOID __regargs DeleteBitMap(struct BitMap *BitMap); STATIC VOID __regargs make_ytable(WORD width,WORD height); STATIC LONG __saveds VBlankServer(VOID); VOID FrameSync(ULONG jiffies); VOID DeleteBuffer(VOID); BYTE CreateBuffer(VOID); VOID SwapBits(VOID); VOID CopyBits(VOID); VOID LoadPalette(UWORD *Palette); WORD *ytable; struct BitMap *DrawBitMap; STATIC struct BitMap *BitMap1,*BitMap2,*OtherBitMap,*OrigBitMap; STATIC WORD table[500]; STATIC struct Interrupt *VBlank; STATIC ULONG Skip; STATIC BYTE SigBit = -1; STATIC BYTE Colours; STATIC UWORD OrigPalette[32]; extern struct Screen *Screen; extern struct Process *ThisProcess; STATIC VOID __regargs make_ytable(WORD width,WORD height) { WORD linebytes,*pt,acc; linebytes = (((width + 15) >> 4) << 1); ytable = &table[0]; pt = ytable; acc = 0; while(--height >= 0) { *pt++ = acc; acc += linebytes; } } STATIC LONG __saveds VBlankServer() { STATIC BYTE Sentinel = FALSE; if(Sentinel && !Skip) { Signal(ThisProcess,(1 << SigBit)); Sentinel = FALSE; } if(Skip) { Sentinel = TRUE; Skip--; } return(0); } VOID FrameSetup(ULONG jiffies) { SetSignal(0,1 << SigBit); Skip = jiffies; } VOID FrameSync() { Wait(1 << SigBit); } VOID DeleteBuffer() { if(VBlank) { RemIntServer(INTB_VERTB,VBlank); FreeMem(VBlank,sizeof(struct Interrupt)); VBlank = NULL; } if(SigBit != -1) { FreeSignal(SigBit); SigBit = -1; } if(OrigBitMap) { UWORD Table[32]; memset(Table,0,sizeof(Table)); LoadRGB4(&Screen -> ViewPort,Table,Colours); Screen -> ViewPort . RasInfo -> BitMap = OrigBitMap; MakeScreen(Screen); RethinkDisplay(); LoadRGB4(&Screen -> ViewPort,OrigPalette,Colours); OrigBitMap = NULL; } if(BitMap1) { DeleteBitMap(BitMap1); BitMap1 = NULL; } if(BitMap2) { DeleteBitMap(BitMap2); BitMap2 = NULL; } } BYTE CreateBuffer() { WORD i; if((Colours = (1 << Screen -> RastPort . BitMap -> Depth)) > 32) Colours = 32; for(i = 0 ; i < Colours ; i++) OrigPalette[i] = GetRGB4(Screen -> ViewPort. ColorMap,i); if(!(BitMap1 = CreateBitMap(Screen -> RastPort . BitMap -> Depth,Screen -> Width,Screen -> Height))) return(FALSE); if(!(BitMap2 = CreateBitMap(Screen -> RastPort . BitMap -> Depth,Screen -> Width,Screen -> Height))) { DeleteBuffer(); return(FALSE); } DrawBitMap = BitMap1; OtherBitMap = BitMap2; make_ytable(Screen -> Width,Screen -> Height); if((SigBit = AllocSignal(-1)) == -1) { DeleteBuffer(); return(FALSE); } if(!(VBlank = (struct Interrupt *)AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC|MEMF_CLEAR))) { DeleteBuffer(); return(FALSE); } VBlank -> is_Node . ln_Name = "FrameSync Interrupt"; VBlank -> is_Node . ln_Type = NT_INTERRUPT; VBlank -> is_Code = (APTR)VBlankServer; Skip = 0; AddIntServer(INTB_VERTB,VBlank); OrigBitMap = Screen -> ViewPort . RasInfo -> BitMap; return(TRUE); } VOID SwapBits() { struct BitMap *Swap; Screen -> ViewPort . RasInfo -> BitMap = DrawBitMap; MakeScreen(Screen); RethinkDisplay(); Swap = OtherBitMap; OtherBitMap = DrawBitMap; DrawBitMap = Swap; } VOID CopyBits() { CopyMem(OtherBitMap -> Planes[0],DrawBitMap -> Planes[0],OtherBitMap -> BytesPerRow * OtherBitMap -> Rows * OtherBitMap -> Depth); } VOID LoadPalette(UWORD *Palette) { LoadRGB4(&Screen -> ViewPort,Palette,Colours); }