Rotate GET/PUT arrays

Area:    Quik_Bas
  Msg:    #289
 Date:    12-11-92 06:33 (Public) 
 From:    Steve Gartrell           
 To:      Geoffrey Liu             
 Subject: Rotate GET/PUT arrays
'For big arrays, this screams for conversion to assembly.
'But, using this, it's just a translation job.
'Remember, this is a pixel by pixel rotation, so at
'angles other than 0 or 180, lettering is reversed.  (You'd
'need to approach it in blocks the size of a standard
'character in whichever screen mode you were in, to do
'writing.  I wasn't going to do it all!!!)
DEFINT A-Z
DECLARE SUB RotateArray (SourceArray%(), TargetArray%(), Angle%)
'Must have the appropriate QB.QLB/QBX.QLB/VBDOS.QLB loaded
' if in the environment-link with appropriate library....
DECLARE SUB ABSOLUTE (Var%, BYVAL HowFar%, address AS INTEGER)
CONST C$ = "Created 12/01/92 by Steve Gartrell"
CONST NumBytes = 21
'$STATIC
DIM SHARED RORproc%(1 TO (NumBytes / 2))
'$DYNAMIC
DIM SHARED BitsPP%, Planes%, MaskBits%
DIM TheScreens%(1 TO 9)
offset% = VARPTR(RORproc%(1))
FOR byte% = 0 TO NumBytes - 1
  READ opcode%
  POKE (offset% + byte%), opcode%
NEXT byte%
TheScreens%(1) = 1
TheScreens%(2) = 2
TheScreens%(3) = 7
TheScreens%(4) = 8
TheScreens%(5) = 9
TheScreens%(6) = 11
TheScreens%(7) = 12
TheScreens%(8) = 13
KEY OFF
ScrCnt% = 8
DO
  SCREEN TheScreens%(ScrCnt%)
  MaskBits% = 128
  SELECT CASE TheScreens%(ScrCnt%)
    CASE 1   'Screen 1
    MaskBits% = 192
    BitsPP% = 2: Planes% = 1
    ColorMod% = 3
    CASE 2   'Screen 2
    BitsPP% = 1: Planes% = 1
    ColorMod% = 2
    CASE 7   'Screen 7
    BitsPP% = 1: Planes% = 4
    ColorMod% = 16
    CASE 8   'Screen 8
    BitsPP% = 1: Planes% = 4
    ColorMod% = 16
    CASE 9  'Screen 9
    BitsPP% = 1: Planes% = 4
    ColorMod% = 16
    CASE 11  'Screen 11
    BitsPP% = 1: Planes% = 1
    ColorMod% = 2
    CASE 12  'Screen 12
    BitsPP% = 1: Planes% = 4
    ColorMod% = 16
    CASE 13  'Screen 13
    MaskBits% = 255
    BitsPP% = 8: Planes% = 1
    ColorMod% = 256
  END SELECT
  StartX% = 119: StartY% = 55: EndX% = 199: EndY% = 135
  ArrayBytes& = 4 + INT(((EndX% - StartX% + 1)_
 * (BitsPP%) + 7) / 8) * Planes% * ((EndY% - StartY%) + 1)
  REDIM SourceArray%(0 TO ArrayBytes& \ 2)
  REDIM BlankArray%(0 TO ArrayBytes& \ 2)
  REDIM TargetArray%(0 TO 20)
  GET (StartX%, StartY%)-(EndX%, EndY%), BlankArray%(0)
  FOR TheLine% = 1 TO 24
    LOCATE TheLine%, 1
    FOR cnt% = 33 TO 72
      SELECT CASE TheScreens%(ScrCnt%)
        CASE 1, 2, 11
        CASE ELSE
          COLOR cnt% MOD ColorMod%
      END SELECT
      PRINT CHR$(cnt%);
    NEXT
    IF TheLine% <> 24 THEN PRINT
  NEXT
  GET (StartX%, StartY%)-(EndX%, EndY%), SourceArray%(0)
  DO
    DO: t$ = UCASE$(INKEY$): LOOP UNTIL LEN(t$)
    SELECT CASE t$
      CASE "Q"  'QUIT!!!!!
        SCREEN 0: WIDTH 80: COLOR 7, 0: END
      CASE "N"  'CHANGE SCREEN MODE!!!
        ScrCnt% = ScrCnt% + 1
        IF ScrCnt% = 9 THEN ScrCnt% = 1
        EXIT DO
      CASE ELSE  'ROTATE!!!!
        Angle% = (Angle% + 90) MOD 360
        RotateArray SourceArray%(), TargetArray%(), Angle%
        WAIT &H3DA, 8, 8
        WAIT &H3DA, 8
        PUT (StartX%, StartY%), BlankArray%(0), PSET
        PUT (StartX%, StartY%), TargetArray%(0), PSET
        ERASE TargetArray%
    END SELECT
  LOOP
LOOP
RotRight:
DATA &H55              : 'push   bp
DATA &H8B,&HEC         : 'mov    bp, sp
DATA &H51              : 'push   cx
DATA &H8B,&H4E,&H06    : 'mov    cx, [bp + 6]
DATA &H8B,&H5E,&H08    : 'mov    bx, [bp + 8]
DATA &H8B,&H07         : 'mov    ax, [bx]
DATA &HD2,&HC8         : 'ror    al, cl
DATA &H89,&H07         : 'mov    [bx], ax
DATA &H59              : 'pop    cx
DATA &H5D              : 'pop    bp
DATA &HCA,&H04,&H00    : 'retf   4
REM $STATIC
DEFSNG A-Z
SUB RotateArray (SourceArray%(), TargetArray%(), Angle%)
DIM SourcePix%(1 TO 4)
DIM SourceBitsPP%, SourceBytesPerRow&, SourceRowOffset&
DIM SourceX%, SourceY%, BytePosCopy&, SourceBytePos&
DIM SourceRightMove%, SourceBitMask%, SourceToTargetDiff%
DIM TargetBitsPP%, TargetBytesPerRow&, TargetRowOffset&
DIM TargetRightMove%, TargetBytePos&, TargetX%, TargetY%
DIM WhichBits%, NumCols%, NumRows%
SELECT CASE BitsPP%
  CASE 1
    WhichBits% = 7
  CASE 2
    WhichBits% = 3
  CASE 8
    WhichBits% = 0
END SELECT
SourceBitsPP% = SourceArray%(0)
NumCols% = SourceBitsPP% \ BitsPP%
NumRows% = SourceArray%(1)
IF Angle% MOD 180 THEN
  'Make it square if it's not!!!
  SELECT CASE NumRows% - NumCols%
    CASE IS < 0
      NumCols% = NumRows%
    CASE IS > 0
      NumRows% = NumCols%
  END SELECT
END IF
TargetBitsPP% = NumCols% * BitsPP%
IF TargetBitsPP% AND 7 THEN
  TargetBytesPerRow& = (TargetBitsPP% \ 8 + 1) * Planes%
ELSE
  TargetBytesPerRow& = (TargetBitsPP% \ 8) * Planes%
END IF
REDIM TargetArray%(0 TO ((TargetBytesPerRow& * NumRows%) \ 2) + 2)
TargetArray%(0) = TargetBitsPP%
TargetArray%(1) = NumRows%
TargetBytesPerPlane% = TargetBytesPerRow& \ Planes%
IF SourceBitsPP% MOD 8 THEN
  SourceBytesPerPlane% = (SourceBitsPP% \ 8 + 1)
ELSE
  SourceBytesPerPlane% = (SourceBitsPP% \ 8)
END IF
SourceBytesPerRow& = SourceBytesPerPlane% * Planes%
SourceRowOffset& = 4
SourceBytePos& = SourceRowOffset&
SourceRightMove% = 0
SourceBitMask% = MaskBits%
FOR SourceY% = 0 TO NumRows% - 1
  FOR SourceX% = 0 TO NumCols% - 1
    SELECT CASE Angle%
      CASE 90
        TargetX% = NumRows% - SourceY% - 1
        TargetY% = NumCols% - SourceX% - 1
      CASE 180
        TargetX% = NumCols% - SourceX% - 1
        TargetY% = NumRows% - SourceY% - 1
      CASE 270
        TargetX% = SourceY%
        TargetY% = SourceX%
      CASE ELSE
        TargetX% = SourceX%
        TargetY% = SourceY%
    END SELECT
    TargetRowOffset& = (TargetY% * TargetBytesPerRow&) + 4
    TargetBytePos& = TargetRowOffset& + ((TargetX% * BitsPP%) \ 8)
    TargetRightMove% = TargetX% AND WhichBits%
    IF BitsPP% = 2 THEN
      TargetRightMove% = TargetRightMove% + TargetRightMove%
    END IF
    SourceToTargetDiff% = (TargetRightMove% - SourceRightMove% + 8) AND 7
    BytePosCopy& = SourceBytePos&
    DEF SEG = VARSEG(SourceArray%(0))
    FOR PlaneNum% = 1 TO Planes%
      SourcePix%(PlaneNum%) = (PEEK(BytePosCopy&) AND SourceBitMask%)
      BytePosCopy& = BytePosCopy& + SourceBytesPerPlane%
    NEXT
    IF SourceToTargetDiff% THEN
      DEF SEG
      RotRight% = VARPTR(RORproc%(1))
-end-

Outer Court
Echo Basic Postings

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