home *** CD-ROM | disk | FTP | other *** search
- ' +===================================================+
- ' | DAZZLING.BAS |
- ' | Written and Developed by: |
- ' | Lawrence Stone |
- ' | |
- ' | Copyright (C), 1990 |
- ' | Lawrence Stone |
- ' | All Rights Reserved |
- ' | |
- ' | The code in this module is for the exclusive |
- ' | use of readers of the QBNews or any QuickBASIC, |
- ' | BASCOM, or PDS programmer. The source code and |
- ' | object modules derived from this code may be |
- ' | freely distributed without the express written |
- ' | permission of the author. |
- ' | |
- ' | Donations of appreciation for this author's |
- ' | work are gladly accepted. Please, no donations |
- ' | over $10,000 <GRIN>. |
- ' | |
- ' | Lawrence Stone November 22, 1990 |
- ' | P.O. Box 5715 |
- ' | Charleston, OR 97420 |
- ' +---------------------------------------------------+
- '
- ' +===================================================+
- ' | Compile swithces: bc dazzling /o; |
- ' +---------------------------------------------------+
-
- ' $INCLUDE: 'DAZZLING.BI'
-
- SUB Curtains (Direction%, Arry%()) STATIC
-
- ' Arry%() The screen image array.
- '
- ' Direction = odd Curtains close from outside toward inside.
- ' Direction = even Curtains open from inside toward outside.
- '
- ' Monitor -+------ Must be DIM SHARED or COMMON SHARED in main module.
- ' ScrnEls /
-
- Start = 79: finish = 159
- StepCount = 2
- start2 = 1: finish2 = ScrnEls * 2
- StepCount2 = 160
- Direction = Direction MOD 2 'Force Direction into a "1" or "0".
-
- IF Direction THEN
- SWAP Start, finish
- StepCount = -StepCount
- SWAP start2, finish2
- finish2 = finish2 - 1
- StepCount2 = -StepCount2
- END IF
-
- FOR N = Start TO finish STEP StepCount
- DEF SEG = Monitor
- FOR J = start2 TO finish2 STEP StepCount2
- IF (N + J) \ 2 < ScrnEls THEN 'Prevents subscript out of range.
- '---- Right side of screen.
- OneByte = Arry((N + J) \ 2) AND &HFF 'Extract high byte.
- count = &H0 - Direction + J + N
- GOSUB CurtainPoke
- OneByte = (Arry((N + J) \ 2) AND &HFF00) \ 256 'Extract low.
- count = &H0 + 1 - Direction + N + J
- GOSUB CurtainPoke
-
- '---- Left side of screen.
- I = (79 - N) * 2
- OneByte = Arry((N + J + I) \ 2) AND &HFF 'Extract high byte.
- count = &H0 - Direction + J + I + N
- GOSUB CurtainPoke
- OneByte = (Arry((N + J + I) \ 2) AND &HFF00) \ 256'Extract low.
- count = &H0 + 1 - Direction + N + J + I
- GOSUB CurtainPoke
- END IF
- NEXT
- DEF SEG 'We must return to BASIC's segment before we call TickPause.
- IF N MOD 3 THEN TickPause 1 'A short delay for effect.
- NEXT
-
- EXIT SUB
-
- CurtainPoke:
- POKE count, OneByte
- RETURN
-
- END SUB
-
- SUB Dazzle (Operation%, Direction%, Arry%()) STATIC
-
- ' Operation Description
- ' --------- ---------------------------------
- ' 0 Pull Full Screen Restore
- ' 1 Dazzled with Stair Steps
- ' 2 Dazzled with 8 Vertical Blinds
- ' 3 Dazzled with 4 Vertical Blinds
- ' 4 Dazzled with Slots
- ' 5 Dazzled with Diagonal Fills
- ' 6 Dazzled with Side Slides
- ' 7 Dazzled with Rolling Grates
- ' 8 Dazzled with Venetian Blinds
- '
- ' Direction = odd Screen restore is left to right or, top to bottom
- ' Direction = even Screen restore is right to left or, bottom to top
- '
- ' Arry%() Screen array
- '
- ' MaxLine \
- ' Monitor -+------ Must be DIM SHARED or COMMON SHARED in main module.
- ' ScrnEls /
-
- GOSUB InitDazzle
-
- FOR J = Start TO finish STEP StepCount 'Force a dazzle.
- DEF SEG = Monitor 'Define segment address.
- FOR N = J TO finish2 STEP StepCount2
- High = Arry(N \ 2) AND &HFF 'Extract the high byte.
- Low = (Arry(N \ 2) AND &HFF00) \ 256 'Extract the low byte.
- POKE &H0 - 1 + N, High 'POKE the high byte (color attr).
- POKE &H0 + N, Low 'POKE the low byte (character).
-
- ' Slow pull down/up windows needed for compiled code if you
- ' don't want it to just "flash" onto the monitor.
- IF Operation = 0 AND N MOD 479 = 0 THEN
- DEF SEG
- TickPause 1
- DEF SEG = Monitor
- END IF
-
- NEXT
- DEF SEG 'Back to BASIC.
-
- '**** Short Pause for added effect.
- IF Operation < 4 THEN
- TickPause 1
- ELSEIF Operation > 7 THEN
- IF J MOD 199 = 0 THEN TickPause 1
- ELSEIF Operation = 7 THEN
- IF J MOD 7 = 0 THEN TickPause 1
- ELSEIF Operation <> 0 THEN
- IF J MOD 3 = 0 THEN TickPause 1
- END IF
- NEXT
-
- EXIT SUB
-
- InitDazzle:
- StepCount = 2: Start = 1: finish2 = ScrnEls * 2
- SELECT CASE Operation
- CASE 0 'Pull Full Screen Restore
- finish = 1: StepCount2 = finish + 1
- IF Direction MOD 2 THEN
- Start = finish2 + 1: finish = Start
- finish2 = 0: StepCount2 = -StepCount2
- END IF
- CASE 1 'Dazzled Stair Steps
- finish = 42: StepCount2 = finish - 4
- CASE 2 'Dazzled with 8 Vertical Blinds
- finish = 20: StepCount2 = finish
- CASE 3 'Dazzled with 4 Vertical Blinds
- finish = 40: StepCount2 = finish
- CASE 4 'Dazzled with Slots
- finish = 119: StepCount2 = finish - 1
- CASE 5 'Dazzled by Diagonal Fills
- finish = 82: StepCount2 = finish
- CASE 6 'Dazzled by Side Slides
- finish = 160: StepCount2 = finish
- CASE 7 'Dazzled by Rolling Grates
- finish = 320: StepCount2 = finish
- CASE 8 'Dazzled with Venetian Blinds
- finish = 80 * MaxLine - MaxLine
- finish = finish - (finish MOD 160) + 160
- StepCount2 = finish
- StepCount2 = StepCount2 + (StepCount2 MOD 80)
- CASE ELSE
- END SELECT
-
- IF Direction MOD 2 = 0 AND Operation% <> 0 THEN
- SWAP Start, finish
- IF NOT Operation = 4 THEN Start = Start - 1
- StepCount = -StepCount
- END IF
- RETURN
-
- END SUB
-
- SUB GetMonitorSeg
-
- ' Monitor Must be DIM SHARED or COMMON SHARED in main module.
-
- DEF SEG = 0
- IF (PEEK(&H410) AND &H30) = &H30 THEN Monitor = &HB000 ELSE Monitor = &HB800
- DEF SEG
-
- END SUB
-
- SUB Implode (Arry%()) STATIC
-
- ' Arry%() The screen image array.
- '
- ' Direction = odd Curtains close from outside toward inside.
- ' Direction = even Curtains open from inside toward outside.
- '
- ' Monitor -+------ Must be DIM SHARED or COMMON SHARED in main module.
- ' ScrnEls /
-
- Start = 1: finish = ScrnEls * 2
- StepCount = 160
- start2 = 0: finish2 = 159
- StepCount2 = 2
-
- FOR N = Start TO finish \ 2 STEP StepCount
- DEF SEG = Monitor
- IF (N) \ 2 < ScrnEls THEN 'Prevents subscript out of range.
- FOR J = start2 TO finish2 STEP StepCount2
- '---- Top side of screen.
- OneByte = Arry((N + J) \ 2) AND &HFF 'Extract high byte.
- count = &H0 - 1 + J + N
- GOSUB ImplodePoke
- OneByte = (Arry((N + J) \ 2) AND &HFF00) \ 256 'Extract low.
- count = &H0 + N + J
- GOSUB ImplodePoke
- NEXT
-
- FOR K = J - 1 TO finish - J - 1 STEP StepCount
- '---- Right side of screen.
- OneByte = Arry(K \ 2) AND &HFF 'Extract high byte.
- count = &H0 - 1 + K
- GOSUB ImplodePoke
- OneByte = (Arry(K \ 2) AND &HFF00) \ 256 'Extract low.
- count = &H0 + K
- GOSUB ImplodePoke
- NEXT
-
- FOR I = finish - N TO finish - N - J + 2 STEP -StepCount2
- '---- Bottom side of screen.
- OneByte = Arry(I \ 2) AND &HFF 'Extract high byte.
- count = &H0 - 1 + I
- GOSUB ImplodePoke
- OneByte = (Arry(I \ 2) AND &HFF00) \ 256 'Extract low.
- count = &H0 + I
- GOSUB ImplodePoke
- NEXT
-
- FOR J = I + 2 TO N STEP -StepCount
- '---- Left side of screen.
- OneByte = Arry(J \ 2) AND &HFF 'Extract high byte.
- count = &H0 - 1 + J
- GOSUB ImplodePoke
- OneByte = (Arry(J \ 2) AND &HFF00) \ 256 'Extract low.
- count = &H0 + J
- GOSUB ImplodePoke
- NEXT
- start2 = start2 + StepCount2: finish2 = finish2 - StepCount2
- END IF
- DEF SEG
- TickPause 1 'Slow compiled programs down to see it happen!
- NEXT
-
- EXIT SUB
-
- ImplodePoke:
- POKE count, OneByte
- RETURN
-
- END SUB
-
- SUB ReadBinFile (Arry%(), ScrFile$, LeadingRows%)
-
- ' Arry%() The screen array to be filled.
- ' ScrFile$ The name of the BIN file to open and read.
- ' LeadingRows% The number of rows in the video array to leave blank.
- '
- ' Note: This routine does no error checking. It is your responsibility
- ' to make sure that ScrFile$ exists before calling this routine.
-
- OPEN ScrFile$ FOR BINARY AS #1 'Open a BIN file.
- N = LOF(1)
- temp$ = INPUT$(N, 1) 'Input 'N' bytes to a work string.
- CLOSE
-
- '---- Calculate a starting point for inserting our screen into the array.
- IF LeadingRows THEN Start = (LeadingRows% * 80)
-
- FOR A = 1 TO N STEP 2
- '---- Combine the two bytes into one, long integer.
- N& = (ASC(MID$(temp$, A, 1)) + 256&) + (ASC(MID$(temp$, A + 1, 1)) * 256&) - 256&
-
- '---- Adjust integer's range to signed short integer range.
- IF N& > 32767 THEN N& = N& - 65536
-
- Arry(Start + A \ 2) = N& 'Assign the integer to the array.
- NEXT
- temp$ = "" 'Clear the temporary string.
-
- END SUB
-
- SUB Shake (HowMany%)
-
- '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- '% %
- '% HumbleWare Custom Programming 12/12/1988 %
- '% %
- '% Routine to "shake" the screen by reprogramming the 6845 %
- '% CRT controllers viewport into video RAM. %
- '% %
- '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- '
- '+===========================================================+
- '| |
- '| Modified by Lawrence Stone Research Group 11/22/1990 |
- '| |
- '| The principle modification made to this routine is the |
- '| substitutions of the TickPause delay routine in lieu of |
- '| the original TIMER + .01 code. |
- '| |
- '+-----------------------------------------------------------+
-
- FOR N = 0 TO HowMany
-
- 'move viewport into video RAM by 3 text lines (ie, this is the number
- 'of lines your entire screen will jump with each shake. -LS)
- Lines% = 3
-
- 'turn text lines into register values
- Lo% = (Lines% * 80) MOD 256
- Ho% = (Lines% * 80) \ 256
-
- 'request access to register 12
- OUT &H3D4, 12
- 'program register 12
- OUT &H3D5, Ho%
-
- 'request access to register 13
- OUT &H3D4, 13
- 'program register 13
- OUT &H3D5, Lo%
-
- 'pause a moment for effect
- TickPause 1
-
- 'restore viewport into video RAM
- Lines% = 0
-
- 'turn text lines into register values
- Lo% = (Lines% * 80) MOD 256
- Ho% = (Lines% * 80) \ 256
-
- 'request access to register 12
- OUT &H3D4, 12
- 'program register 12
- OUT &H3D5, Ho%
-
- 'request access to register 13
- OUT &H3D4, 13
- 'program register 13
- OUT &H3D5, Lo%
-
- 'pause a moment for effect
- TickPause 1
-
- NEXT
-
- END SUB
-
- SUB StuffMess (Arry%(), Mess$, Row%, Col%, Fg%, Bg%) STATIC
-
- ' Arry%() Screen image array.
- ' Mess$ Message to place into the screen image array.
- ' Row% Screen row location for the message.
- ' Col% Screen column location for the message.
- ' Fg% Foreground color of the message.
- ' Bg% Background color of the message.
-
- '---- Convert Foreground & Baground colors to a screen attribute integer.
- BColr = Bg * 16 'Put color into proper range.
- FColr = Fg 'Set forground color.
- IF FColr > 15 THEN BColr = BColr + 128 'Set blink attribute.
- FColr = FColr AND 15 'Remove blink attribute.
- Colr = FColr + BColr 'Create screen attribute integer.
-
- '---- Combine the Row & Col position into a starting point for video map.
- Start = (((Row * 160) - 160) + (Col * 2)) - 2
-
- ArySeg = VARSEG(Arry%(0)) 'Segment address of the array.
- AryPtr = VARPTR(Arry%(0)) 'Offset of the array.
- I = 0 'Initialize position counter.
-
- DEF SEG = ArySeg
- FOR J = 1 TO LEN(Mess$) 'Loop thru message.
- POKE AryPtr + Start + I, ASC(MID$(Mess$, J, 1)) 'POKE the character.
- POKE AryPtr + Start + I + 1, Colr 'POKE the color.
- I = I + 2 'Increment 'I' by 2.
- NEXT
- DEF SEG
-
- END SUB
-
- SUB TickPause (Ticks%) STATIC
-
- ' Ticks% The number of ticks to delay. There are 18.2 ticks
- ' per second. This routine returns the ticks as an
- ' integer - it does not use QB's floating point routine.
-
- TestTick = 0
-
- DEF SEG = zero
- WHILE TestTick < Ticks
-
- lastTick = Tick
- Tick = PEEK(&H46C) 'Get a tick from the clock.
-
- ' ---- Prevents endless loop when rolling past midnight.
- IF lastTick <> Tick THEN TestTick = TestTick + 1
-
- WEND
- DEF SEG
-
- END SUB
-
-