Area: Quik_Bas Msg: #323 Date: 01-18-93 11:37 (Public) From: Matt Hart To: All Subject: Screen Saver
Continued from previous... SUB HSSaveScreen(ScreenFile$,X1,Y1,X2,Y2,MonType,ScrNum) F = FREEFILE OPEN ScreenFile$ FOR BINARY AS F IF LOF(F) THEN SEEK F,LOF(F)-1 Z$ = " " : GET F,,Z$ : NumScreens = CVI(Z$)+1 REDIM Scrs(1 TO NumScreens) AS HSDefScrsType SeekPos& = LOF(F) - LEN(Scrs(1))*(NumScreens-1)-1 SEEK F,SeekPos& FOR i = 1 TO NumScreens - 1 GET F,,Scrs(i) NEXT ELSE NumScreens = 1 REDIM Scrs(1 TO NumScreens) AS HSDefScrsType SeekPos& = 1 ENDIF ScrNum = NumScreens DEF SEG = 0 : BIOSMode = PEEK(&H449) : DEF SEG SELECT CASE BIOSMode CASE 3 ScrMode = 0 : NumBytes& = (X2-X1+1)*2 * (Y2-Y1+1) CASE 4 ScrMode = 1 : BPP = 2 : P = 1 : GOSUB CalcBytes CASE 6 ScrMode = 2 : BPP = 1 : P = 1 : GOSUB CalcBytes CASE 13 ScrMode = 7 : BPP = 1 : P = 4 : GOSUB CalcBytes CASE 14 ScrMode = 8 : BPP = 1 : P = 4 : GOSUB CalcBytes CASE 16 ScrMode = 9 : BPP = 1 : P = 4 GOSUB CalcBytes ' P = 2 for 64K EGA CASE 15 ScrMode = 10 : BPP = 1 : P = 2 : GOSUB CalcBytes CASE 17 ScrMode = 11 : BPP = 1 : P = 1 GOSUB CalcBytes : NumPal = 2 CASE 18 ScrMode = 12 : BPP = 1 : P = 4 GOSUB CalcBytes : NumPal = 16 CASE 19 ScrMode = 13 : BPP = 8 : P = 1 GOSUB CalcBytes : NumPal = 256 END SELECT DimSize = NumBytes& \ 4 + 1 REDIM Store&(1 TO DimSize) TSeg = VARSEG(Store&(1)) : TAddr = VARPTR(Store&(1)) ActualBytes& = 0& IF ScrMode > 0 THEN GOSUB GetGraphics : GOTO SaveIt IF MonType THEN FSeg = &HB800 ELSE FSeg = &HB000 ' Good candidate for assembly NumCols = X2-X1 FOR l = Y1 TO Y2 Addr = (X1-1)*2 + (l-1)*160 FOR i = Addr TO Addr+(NumCols*2) STEP 2 DEF SEG = FSeg Char = PEEK(i) DEF SEG = TSeg POKE TAddr,Char TAddr = TAddr + 1 ActualBytes& = ActualBytes& + 1& NEXT NEXT FOR l = Y1 TO Y2 Addr = (X1-1)*2+1 + (l-1)*160 FOR i = Addr TO Addr+(NumCols*2) STEP 2 DEF SEG = FSeg Attr = PEEK(i) DEF SEG = TSeg POKE TAddr,Attr TAddr = TAddr + 1 ActualBytes& = ActualBytes& + 1& NEXT NEXT SaveIt: DimSize = ActualBytes& \ 4& + 4096 ' Extra 4K just in case REDIM RLL&(1 TO DimSize) CALL HSRLLCompress(Store&(), RLL&(), ActualBytes&, RLLBytes&) Scrs(NumScreens).RLLBytes = RLLBytes& Scrs(NumScreens).ActualBytes = ActualBytes& Scrs(NumScreens).Offset = SeekPos& Scrs(NumScreens).X1 = X1 Scrs(NumScreens).Y1 = Y1 Scrs(NumScreens).X2 = X2 Scrs(NumScreens).Y2 = Y2 Scrs(NumScreens).ScrMode = ScrMode Scrs(NumScreens).MonType = MonType FSeg = VARSEG(RLL&(1)) FAddr = VARPTR(RLL&(1)) SEEK F,SeekPos& SaveSize = RLLBytes& \ 4 + 1 FOR i = 1 TO SaveSize Z$ = MKL$(RLL&(i)) PUT F,,Z$ NEXT IF ScrMode > 10 THEN DIM Pal(1 TO NumPal) AS STRING * 3 DIM InRegs AS RegTypeX DIM OutRegs AS RegTypeX InRegs.AX = &H1017 InRegs.BX = 0 InRegs.CX = NumPal InRegs.ES = VARSEG(Pal(1)) InRegs.DX = VARPTR(Pal(1)) CALL INTERRUPTX(&H10, InRegs, OutRegs) FOR i = 1 TO NumPal PUT F,,Pal(i) NEXT ENDIF FOR i = 1 TO NumScreens PUT F,,Scrs(i) NEXT Z$ = MKI$(NumScreens) : PUT F,,Z$ CLOSE F EXIT SUB GetGraphics: GET (X1,Y1)-(X2,Y2),Store&(1) ActualBytes& = NumBytes& RETURN CalcBytes: N& = ((X2-X1+1)*BPP) : NumBytes& = N&\8 - ((N& MOD 8) > 0) NumBytes& = NumBytes& * P * (Y2-Y1+1) + 4 RETURN END SUB ' Good candidate for assembly SUB HSRLLCompress(Store&(), RLL&(), ActualBytes&, RLLBytes&) RLLBytes& = 0& FSeg = VARSEG(Store&(1)) : FAddr = VARPTR(Store&(1)) TSeg = VARSEG(RLL&(1)) : TAddr = VARPTR(RLL&(1)) FOR i& = 1& TO ActualBytes& DEF SEG = FSeg Z = PEEK(FAddr) CALL HSIncAddr(FSeg,FAddr,1) IF i& < ActualBytes&-2 AND_ PEEK(FAddr) = Z AND_ PEEK(FAddr+1) = Z AND_ PEEK(FAddr+2) = Z THEN Num = 4 i& = i& + 3 CALL HSIncAddr(FSeg,FAddr,3) DO UNTIL PEEK(FAddr) <> Z OR i& > ActualBytes& IF Num = 255 THEN EXIT DO Num = Num + 1 i& = i& + 1 CALL HSIncAddr(FSeg,FAddr,1) LOOP RLLBytes& = RLLBytes& + 3 DEF SEG = TSeg POKE TAddr,0 : CALL HSIncAddr(TSeg,TAddr,1) POKE TAddr,Num : CALL HSIncAddr(TSeg,TAddr,1) POKE TAddr,Z : CALL HSIncAddr(TSeg,TAddr,1) ELSEIF Z = 0 THEN DEF SEG = TSeg POKE TAddr,0 : CALL HSIncAddr(TSeg,TAddr,1) POKE TAddr,0 : CALL HSIncAddr(TSeg,TAddr,1) RLLBytes& = RLLBytes& + 2 ELSE DEF SEG = TSeg POKE TAddr,Z : CALL HSIncAddr(TSeg,TAddr,1) RLLBytes& = RLLBytes& + 1 ENDIF NEXT ERASE Store& END SUB ' Good candidate for assembly SUB HSIncAddr(DSeg,DAddr,Num) IF CLNG(DAddr) + Num > 32751& THEN DAddr = DAddr - 32752& + Num DSeg = DSeg + 2047 DEF SEG = DSeg ELSE DAddr = DAddr + Num ENDIF END SUB SUB HSRestoreScreen(ScreenFile$,X1,Y1,MonType,ScrNum) F = FREEFILE OPEN ScreenFile$ FOR BINARY AS F IF LOF(F) = 0 THEN CLOSE F : EXIT SUB SEEK F,LOF(F)-1 -end-
Books at Amazon:
Back to BASIC: The History, Corruption, and Future of the Language
Hackers: Heroes of the Computer Revolution (including Tiny BASIC)
Go to: The Story of the Math Majors, Bridge Players, Engineers, Chess Wizards, Scientists and Iconoclasts who were the Hero Programmers of the Software Revolution
The Advent of the Algorithm: The Idea that Rules the World
Moths in the Machine: The Power and Perils of Programming
Mastering Visual Basic .NET