'View RGB '作者:zyl910
'使用有序抖动算法(dither)绘制线性渐变区域、RGB色彩空间(Screen 12下) ' Up , Down , PageUp , PageDown: 改变B分量 ' F4~F8: 改变背景 ' Esc: 退出 '直接在QB环境下运行速度很慢,编译为exe后就快些了
'展示了以下技术: '1.QB在 VGA 12h 如何快速绘图 '2.有序抖动算法的实现 '3.模拟Windows窗口,特别是像Windows 98那样的渐变标题栏
'== Rect ===================================================================== TYPE Rect Left AS INTEGER Top AS INTEGER Right AS INTEGER Bottom AS INTEGER END TYPE
CONST RectNoNum = &H8000
DECLARE FUNCTION GetRectW% (rct AS Rect) DECLARE FUNCTION GetRectH% (rct AS Rect) DECLARE SUB SetRect (rct AS Rect, x1%, y1%, x2%, y2%) DECLARE SUB SetRectPos (rct AS Rect, x%, y%) DECLARE SUB SetRectSize (rct AS Rect, w%, h%) DECLARE SUB MoveRect (rct AS Rect, x%, y%) DECLARE SUB SizeRect (rct AS Rect, x%, y%) DECLARE SUB SetRectMinMax (rct AS Rect, MinX%, MinY%, MaxX%, MaxY%) DECLARE SUB RectAddSize (rct AS Rect, xAdd AS INTEGER, yAdd AS INTEGER) DECLARE FUNCTION RectIsNull% (rct AS Rect)
'== Bit ====================================================================== DECLARE SUB InitBit () DECLARE FUNCTION MakeWord% (LoByte AS INTEGER, HiByte AS INTEGER)
CONST True = -1 CONST False = 0 '== MemCopy ================================================================== DECLARE SUB InitMemCopy () DECLARE SUB MemCopy (fromseg%, fromoffset%, toseg%, tooffset%, bytes%)
'== Font ===================================================================== DECLARE SUB InitFont () DECLARE SUB DrawText (rct AS Rect, DrawStr AS STRING) DECLARE SUB DrawTextEx (rct AS Rect, StepX AS INTEGER, StepY AS INTEGER, DrawStr AS STRING, c AS INTEGER)
CONST CharWi = 8 CONST CharHe = 16
'== Color ==================================================================== DECLARE SUB InitLightM () DECLARE FUNCTION RGB12% (x%, y%, R%, G%, B%)
'== Draw ===================================================================== DECLARE SUB DrawEdge (qrc AS Rect, Edge AS INTEGER) DECLARE SUB DrawEdge0 (qrc AS Rect, Edge AS INTEGER)
CONST BdrRAISEDOUTER = &H1 '外层凸 CONST BdrSUNKENOUTER = &H2 '外层凹 CONST BdrRAISEDINNER = &H4 '内层凸 CONST BdrSUNKENINNER = &H8 '内层凹 CONST BdrRAISED = &H5 '凸 CONST BdrSUNKEN = &HA '凹 CONST BdrOuter = &H3 '外 CONST BdrInner = &HC '内
CONST EdgeRAISED = (BdrRAISEDOUTER OR BdrRAISEDINNER) CONST EdgeETCHED = (BdrSUNKENOUTER OR BdrRAISEDINNER) CONST EdgeBUMP = (BdrRAISEDOUTER OR BdrSUNKENINNER) CONST EdgeSUNKEN = (BdrSUNKENOUTER OR BdrSUNKENINNER)
DECLARE SUB FillRect (rct AS Rect, c AS INTEGER)
CONST OnlyLine = &H8000
DECLARE SUB GradH12 (rct AS Rect, cl%, cr%) DECLARE SUB GradV12 (rct AS Rect, ct%, cb%)
DECLARE SUB DrawForm (rct AS Rect, TitleStr AS STRING) DECLARE SUB DrawCaption (rct AS Rect, TitleStr AS STRING)
'== Shared Var =============================================================== DIM SHARED BitMaskInt(0 TO &HF) AS INTEGER
DIM SHARED ASM.MemCopy AS STRING * 28
DIM SHARED FontData(0 TO &HF, 0 TO &HFF) AS INTEGER DIM SHARED TextC AS INTEGER DIM SHARED TextStepX AS INTEGER DIM SHARED TextStepY AS INTEGER DIM SHARED TextLf AS INTEGER DIM SHARED AutoLf AS INTEGER DIM SHARED CharAdd AS INTEGER DIM SHARED LineAdd AS INTEGER
DIM SHARED BaseLightnessMatrix(0 TO 15, 0 TO 15) AS INTEGER DIM SHARED LightnessMatrix(0 TO 15, 0 TO 15) AS INTEGER DIM SHARED RGBIndex(0 TO 1, 0 TO 1, o TO 1) AS INTEGER
'== Const ==================================================================== CONST MyTitle = "View RGB (For QB) V1.0"
CONST ScrColor = 3 CONST ScrWi = 640 CONST ScrHe = 480 CONST MaxWi = ScrWi - 1 CONST MaxHe = ScrHe - 1
CONST TitleHe = 18 CONST TitleLC = 1 CONST TitleRC = 9
CONST CapHe = 1 + TitleHe + 1 CONST EdgeSize = 2 CONST FormBkC = 7 CONST FormTitleC = &HF
CONST FormTop = EdgeSize + CapHe CONST FormLeft = EdgeSize + 1 CONST FormRight = EdgeSize + 1 CONST FormBottom = EdgeSize + 1
CONST FormStep = 4 CONST MapWi = &H100 CONST MapHe = &H100 CONST MaxMapWi = MapWi - 1 CONST MaxMapHe = MapHe - 1 CONST SolWi = &H10
CONST CurW = 8 CONST CurH = 5
'== Var ====================================================================== DIM I AS INTEGER, J AS INTEGER, K AS INTEGER DIM ScrRect AS Rect DIM FormRect AS Rect DIM MyMap(0 TO ((MapWi / 8) * 4 / 2) * MapHe + 1) AS INTEGER DIM valueB AS INTEGER DIM Idx0 AS INTEGER, Idx AS INTEGER, CurIdx AS INTEGER DIM TempInt(0 TO 3) AS INTEGER DIM c AS INTEGER DIM rct AS Rect DIM HSB(0 TO 6) AS INTEGER DIM ik AS STRING DIM KeyCode AS INTEGER
DIM CurMap(0 TO ((CurW + 7) / 8) * 4 * CurH / 2 + 1) AS INTEGER
'== Begin ==================================================================== SCREEN 12
InitMemCopy InitBit InitFont InitLightM
GOSUB LoadCur
HSB(0) = &HC HSB(1) = &HE HSB(2) = &HA HSB(3) = &HB HSB(4) = &H9 HSB(5) = &HD HSB(6) = &HC
SetRect ScrRect, 0, 0, ScrWi, ScrHe FillRect ScrRect, ScrColor 'GradV12 ScrRect, 10, 2
WHILE INKEY$ <> "": WEND 'Clean Key
GOSUB MakeMap
FormRect.Left = 0 FormRect.Top = 0 FormRect.Right = FormLeft + FormStep + MapWi + FormStep + SolWi + CurW + FormStep + FormRight FormRect.Bottom = FormTop + FormStep + MapHe + FormStep + FormBottom SetRectPos FormRect, (ScrWi - FormRect.Right) / 2, (ScrHe - FormRect.Bottom) / 2 GOSUB DrawMe
'WHILE INKEY$ = "": WEND DO ik = INKEY$ IF ik <> "" THEN IF LEN(ik) > 1 THEN KeyCode = ASC(MID$(ik, 2, 1)) SELECT CASE KeyCode CASE 72'Up IF valueB > 0 THEN GOSUB DrawCur valueB = valueB - 1 GOSUB DrawCur GOSUB MakeMap GOSUB DrawMap END IF
CASE 80'Down IF valueB < &HFF THEN GOSUB DrawCur valueB = valueB + 1 GOSUB DrawCur GOSUB MakeMap GOSUB DrawMap END IF
CASE 73 'PageUp IF valueB > 0 THEN GOSUB DrawCur valueB = valueB - &H10 IF valueB < 0 THEN valueB = 0 GOSUB DrawCur GOSUB MakeMap GOSUB DrawMap END IF
CASE 81 'PageDown IF valueB < &HFF THEN GOSUB DrawCur valueB = valueB + &H10 IF valueB > &HFF THEN valueB = &HFF GOSUB DrawCur GOSUB MakeMap GOSUB DrawMap END IF
CASE 62 'F4 FillRect ScrRect, ScrColor GOSUB DrawMe
CASE 63 'F5 GradH12 ScrRect, 10, 2 GOSUB DrawMe
CASE 64 'F6 GradV12 ScrRect, 10, 2 GOSUB DrawMe
CASE 65 'F7 rct.Top = 0 rct.Bottom = ScrHe FOR I = 1 TO 6 rct.Left = (I - 1) * ScrWi / 6 rct.Right = I * ScrWi / 6 GradH12 rct, HSB(I - 1), HSB(I)
NEXT I GOSUB DrawMe
CASE 66 'F8 rct.Left = 0 rct.Right = ScrWi FOR I = 1 TO 6 rct.Top = (I - 1) * ScrHe / 6 rct.Bottom = I * ScrHe / 6 GradV12 rct, HSB(I - 1), HSB(I)
NEXT I GOSUB DrawMe
END SELECT
ELSE KeyCode = ASC(ik) SELECT CASE KeyCode CASE 27 'Esc EXIT DO END SELECT
END IF
END IF
LOOP
SCREEN 0
END
LoadCur: LINE (0, 0)-(CurW - 1, CurH - 1), 0, BF LINE (CurW / 2, 0)-(0, CurH / 2), &HF LINE -(CurW / 2, CurH - 1), &HF LINE -(CurW - 1, CurH - 1), &HF LINE -(CurW - 1, 0), &HF LINE -(CurW / 2, 0), &HF PAINT (CurW / 2, CurH / 2), &HF GET (0, 0)-(CurW - 1, CurH - 1), CurMap
'WHILE INKEY$ = "": WEND
RETURN
DrawCur: PUT (FormRect.Left + FormLeft + FormStep + MapWi + FormStep + SolWi, FormRect.Top + FormTop + FormStep + valueB - CurH / 2), CurMap, XOR
RETURN
MakeMap: MyMap(0) = MapWi MyMap(1) = MapHe Idx0 = 2 FOR I = 0 TO MaxMapHe FOR J = 0 TO MaxMapWi CurIdx = J AND &HF IF CurIdx = 0 THEN FOR K = 0 TO 3 TempInt(K) = 0 NEXT K END IF
c = RGB12(I, J, I, J, valueB) FOR K = 0 TO 3 IF BitMaskInt(7 - K) AND c THEN TempInt(K) = TempInt(K) OR BitMaskInt(CurIdx) NEXT K
IF CurIdx = &HF THEN Idx = Idx0 FOR K = 0 TO 3 MyMap(Idx) = TempInt(K) Idx = Idx + &H10 'MapWi/8/2
NEXT K Idx0 = Idx0 + 1 END IF
NEXT J Idx0 = Idx0 + &H30 '(MapWi/8/2)*3
NEXT I
RETURN
DrawMap: PUT (FormRect.Left + FormLeft + FormStep, FormRect.Top + FormTop + FormStep), MyMap, PSET RETURN
DrawMe: DrawForm FormRect, MyTitle SetRect rct, 0, 0, SolWi, MapHe MoveRect rct, FormLeft + FormStep + MapWi + FormStep, FormTop + FormStep MoveRect rct, FormRect.Left, FormRect.Top GradV12 rct, 0, 9 GOSUB DrawMap GOSUB DrawCur
RETURN
'有序抖动亮度趋势矩阵 DATA 00,EB,3B,DB,0F,E7,37,D7,02,E8,38,D9,0C,E5,34,D5 DATA 80,40,BB,7B,8F,4F,B7,77,82,42,B8,78,8C,4C,B4,74 DATA 21,C0,10,FB,2F,CF,1F,F7,22,C2,12,F8,2C,CC,1C,F4 DATA A1,61,90,50,AF,6F,9F,5F,A2,62,92,52,AC,6C,9C,5C DATA 08,E1,30,D0,05,EF,3F,DF,0A,E2,32,D2,06,EC,3C,DC DATA 88,48,B0,70,85,45,BF,7F,8A,4A,B2,72,86,46,BC,7C DATA 29,C8,18,F0,24,C5,14,FF,2A,CA,1A,F2,26,C6,16,FC DATA A9,69,98,58,A4,64,94,54,AA,6A,9A,5A,A6,66,96,56 DATA 03,E9,39,D8,0D,E4,35,D4,01,EA,3A,DA,0E,E6,36,D6 DATA 83,43,B9,79,8D,4D,B5,75,81,41,BA,7A,8E,4E,B6,76 DATA 23,C3,13,F9,2D,CD,1D,F5,20,C1,11,FA,2E,CE,1E,F6 DATA A3,63,93,53,AD,6D,9D,5D,A0,60,91,51,AE,6E,9E,5E DATA 0B,E3,33,D3,07,ED,3D,DD,09,E0,31,D1,04,EE,3E,DE DATA 8B,4B,B3,73,87,47,BD,7D,89,49,B1,71,84,44,BE,7E DATA 2B,CB,1B,F3,27,C7,17,FD,28,C9,19,F1,25,C4,15,FE DATA AB,6B,9B,5B,A7,67,97,57,A8,68,99,59,A5,65,95,55
SUB DrawCaption (rct AS Rect, TitleStr AS STRING) DIM TempRect AS Rect
TempRect.Left = rct.Left + EdgeSize TempRect.Top = rct.Top + EdgeSize TempRect.Right = rct.Right - EdgeSize SetRectSize TempRect, RectNoNum, CapHe FillRect TempRect, FormBkC OR OnlyLine
SizeRect TempRect, -1, -1 GradH12 TempRect, TitleLC, TitleRC
DrawTextEx TempRect, 3, 1, TitleStr, FormTitleC
END SUB
SUB DrawEdge (qrc AS Rect, Edge AS INTEGER) DIM Inner AS INTEGER, Outer AS INTEGER DIM TempRect AS Rect
Inner = Edge AND BdrInner Outer = Edge AND BdrOuter
TempRect = qrc IF Outer = 0 THEN ELSEIF Outer = BdrOuter THEN ELSE DrawEdge0 TempRect, Outer SizeRect TempRect, -1, -1 END IF IF Inner = 0 THEN ELSEIF Inner = BdrInner THEN ELSE DrawEdge0 TempRect, Inner END IF
END SUB
SUB DrawEdge0 (qrc AS Rect, Edge AS INTEGER) CONST c0 = &H0 CONST c1 = &H8 CONST c2 = &H7 CONST c3 = &HF
DIM clt AS INTEGER, crb AS INTEGER
IF qrc.Right <= qrc.Left THEN EXIT SUB IF qrc.Bottom <= qrc.Top THEN EXIT SUB
SELECT CASE Edge CASE BdrRAISEDOUTER clt = c2 crb = c0 CASE BdrSUNKENOUTER clt = c1 crb = c3 CASE BdrRAISEDINNER clt = c3 crb = c1 CASE BdrSUNKENINNER clt = c0 crb = c2 END SELECT
LINE (qrc.Left, qrc.Top)-(qrc.Right - 1, qrc.Top), clt LINE (qrc.Left, qrc.Top)-(qrc.Left, qrc.Bottom - 1), clt LINE (qrc.Right - 1, qrc.Top)-(qrc.Right - 1, qrc.Bottom - 1), crb LINE (qrc.Left, qrc.Bottom - 1)-(qrc.Right - 1, qrc.Bottom - 1), crb
END SUB
SUB DrawForm (rct AS Rect, TitleStr AS STRING) FillRect rct, FormBkC DrawEdge rct, EdgeRAISED
DrawCaption rct, TitleStr
END SUB
SUB DrawText (rct AS Rect, DrawStr AS STRING) DIM TempRect AS Rect DIM PosX AS INTEGER, PosY AS INTEGER DIM StrLen AS INTEGER DIM StrPos AS INTEGER DIM c AS STRING * 1 DIM FontPos AS INTEGER DIM DrawMinX AS INTEGER, DrawMinY AS INTEGER DIM DrawMaxX AS INTEGER, DrawMaxY AS INTEGER DIM DrawY AS INTEGER DIM DrawX1 AS INTEGER, DrawX2 AS INTEGER DIM ExitFlags AS INTEGER DIM I AS INTEGER DIM MinI AS INTEGER, MaxI AS INTEGER DIM TempNum AS INTEGER
PosX = rct.Left + TextStepX PosY = rct.Top + TextStepY TempRect = rct 'PRINT rct.Top, rct.Bottom SetRectMinMax TempRect, 0, 0, ScrWi, ScrHe IF RectIsNull(TempRect) THEN EXIT SUB RectAddSize TempRect, -1, -1 'PRINT TempRect.Top, TempRect.Bottom DrawMinX = TempRect.Left - (CharWi - 1) DrawMinY = TempRect.Top - (CharHe - 1) DrawMaxX = TempRect.Right + (CharWi - 1) DrawMaxY = TempRect.Bottom + (CharHe - 1) 'PRINT DrawMinY, DrawMaxY DrawX1 = PosX DrawY = PosY StrLen = LEN(DrawStr) IF StrLen = 0 THEN EXIT SUB StrPos = 1 'PRINT StrLen DO c = MID$(DrawStr, StrPos, 1) FontPos = ASC(c) 'PRINT TextLf; c; " "; IF ((FontPos = 13) OR (FontPos = 10)) AND TextLf THEN 'PRINT FontPos DrawX1 = PosX DrawY = DrawY + LineAdd IF StrPos < StrLen OR FontPos = 13 THEN 'CrLf IF ASC(MID$(DrawStr, StrPos + 1, 1)) = 10 THEN StrPos = StrPos + 1 END IF
END IF
IF DrawX1 + CharWi >= TempRect.Right THEN IF AutoLf THEN DrawX1 = PosX DrawY = DrawY + LineAdd ELSE ExitFlags = True END IF END IF
IF DrawY >= DrawMinY AND DrawY <= DrawMaxY THEN DrawX2 = DrawX1 + CharWi - 1 IF DrawX2 >= DrawMinX OR DrawX1 <= DrawMaxX THEN IF DrawX1 < TempRect.Left THEN DrawX1 = TempRect.Left IF DrawX1 > TempRect.Right THEN DrawX1 = TempRect.Right IF DrawX2 < TempRect.Left THEN DrawX2 = TempRect.Left IF DrawX2 > TempRect.Right THEN DrawX2 = TempRect.Right DrawX2 = DrawX2 - DrawX1
TempNum = DrawY IF TempNum < TempRect.Top THEN TempNum = TempRect.Top IF TempNum > TempRect.Bottom THEN TempNum = TempRect.Bottom MinI = TempNum - DrawY TempNum = DrawY + CharHe - 1 IF TempNum < TempRect.Top THEN TempNum = TempRect.Top IF TempNum > TempRect.Bottom THEN TempNum = TempRect.Bottom MaxI = TempNum - DrawY
FOR I = MinI TO MaxI LINE (DrawX1, DrawY + I)-STEP(DrawX2, 0), TextC, , FontData(I, FontPos) NEXT I
END IF
END IF DrawX1 = DrawX1 + CharAdd StrPos = StrPos + 1 IF StrPos > StrLen THEN ExitFlags = True
'ExitFlags = True
LOOP UNTIL ExitFlags
END SUB
SUB DrawTextEx (rct AS Rect, StepX AS INTEGER, StepY AS INTEGER, DrawStr AS STRING, c AS INTEGER) DIM tX AS INTEGER, tY AS INTEGER DIM tC AS INTEGER
tX = TextStepX TextStepX = StepX tY = TextStepY TextStepY = StepY tC = TextC TextC = c DrawText rct, DrawStr TextStepX = tX TextStepY = tY TectX = tC
END SUB
SUB FillRect (rct AS Rect, c AS INTEGER) IF c AND OnlyLine THEN LINE (rct.Left, rct.Top)-(rct.Right - 1, rct.Bottom - 1), c AND &HFF, B ELSE LINE (rct.Left, rct.Top)-(rct.Right - 1, rct.Bottom - 1), c, BF END IF END SUB
FUNCTION GetRectH% (rct AS Rect) GetRectH% = rct.Bottom - rct.Top END FUNCTION
FUNCTION GetRectW% (rct AS Rect) GetRectW% = rct.Right - rct.Left END FUNCTION
SUB GradH12 (rct AS Rect, cl%, cr%) DIM w AS INTEGER, h AS INTEGER DIM I AS INTEGER, J AS INTEGER, K AS INTEGER DIM DataArr(I) AS INTEGER DIM MapArr(I) AS INTEGER DIM Idx AS INTEGER DIM StartIdx AS INTEGER DIM Idx0 AS INTEGER, Idx1 AS INTEGER DIM ChanBytes AS INTEGER, ChanInts AS INTEGER DIM TempInt(0 TO 3) AS INTEGER 'DIM TempNum AS INTEGER DIM c AS INTEGER
w = GetRectW(rct) h = GetRectH(rct) 'PRINT w, h IF h <= 0 THEN EXIT SUB IF w <= 2 THEN EXIT SUB
ChanBytes = (w + 7) / 8 ChanInts = (ChanBytes + 1) / 2 REDIM MapArr(0 TO ChanBytes * 2 + 1) AS INTEGER 'ChanBytes*4/2=ChanBytes*2 MapArr(0) = w MapArr(1) = 1
w = w - 1 h = h - 1 REDIM DataArr(0 TO w) AS INTEGER FOR I = 0 TO w DataArr(I) = I * &H100& / w NEXT I
IF (ChanBytes AND 1) = 0 THEN FOR I = 0 TO h StartIdx = 2 FOR J = 0 TO w Idx = J AND &HF
IF BaseLightnessMatrix(Idx, I AND &HF) >= DataArr(J) THEN c = cl% ELSE c = cr%
FOR K = 0 TO 3 IF BitMaskInt(7 - K) AND c THEN TempInt(K) = TempInt(K) OR BitMaskInt(Idx) NEXT K
IF Idx = &HF OR J = w THEN Idx0 = StartIdx FOR K = 0 TO 3 MapArr(Idx0) = TempInt(K) Idx0 = Idx0 + ChanInts TempInt(K) = 0 NEXT K StartIdx = StartIdx + 1
END IF
NEXT J PUT (rct.Left, rct.Top + I), MapArr, PSET NEXT I ELSE DIM TempArr(0 TO ChanInts - 1, 0 TO 1) AS INTEGER
FOR I = 0 TO h StartIdx = 2 Idx1 = 0 FOR J = 0 TO w Idx = J AND &HF
IF LightnessMatrix(Idx, I AND &HF) >= DataArr(J) THEN c = cl% ELSE c = cr%
FOR K = 0 TO 3 IF BitMaskInt(7 - K) AND c THEN TempInt(K) = TempInt(K) OR BitMaskInt(Idx) NEXT K
IF Idx = &HF OR J = w THEN Idx0 = StartIdx FOR K = 0 TO 3 STEP 2 MapArr(Idx0) = TempInt(K) TempArr(Idx1, K / 2) = TempInt(K + 1) Idx0 = Idx0 + ChanBytes TempInt(K) = 0 TempInt(K + 1) = 0 NEXT K StartIdx = StartIdx + 1 Idx1 = Idx1 + 1
END IF
NEXT J Idx0 = VARSEG(MapArr(0)) Idx1 = VARPTR(MapArr(0)) Idx1 = Idx1 + 2 * 2 + ChanBytes MemCopy VARSEG(TempArr(0, 0)), VARPTR(TempArr(0, 0)), Idx0, Idx1, ChanBytes Idx1 = Idx1 + ChanBytes * 2 MemCopy VARSEG(TempArr(0, 1)), VARPTR(TempArr(0, 1)), Idx0, Idx1, ChanBytes PUT (rct.Left, rct.Top + I), MapArr, PSET NEXT I
END IF
END SUB
SUB GradV12 (rct AS Rect, ct%, cb%) DIM w AS INTEGER, h AS INTEGER DIM I AS INTEGER, J AS INTEGER, K AS INTEGER DIM DataArr(I) AS INTEGER DIM MapArr(I) AS INTEGER DIM Idx AS INTEGER DIM StartIdx AS INTEGER DIM Idx0 AS INTEGER, Idx1 AS INTEGER DIM ChanBytes AS INTEGER, ChanInts AS INTEGER DIM TempInt(0 TO 3) AS INTEGER DIM TempNum AS INTEGER DIM c AS INTEGER
w = GetRectW(rct) h = GetRectH(rct) 'PRINT w, h IF w <= 0 THEN EXIT SUB IF h <= 2 THEN EXIT SUB
ChanBytes = (w + 7) / 8 ChanInts = (ChanBytes + 1) / 2 REDIM MapArr(0 TO ChanBytes * 2 + 1) AS INTEGER 'ChanBytes*4/2=ChanBytes*2 MapArr(0) = w MapArr(1) = 1
w = w - 1 h = h - 1
IF (ChanBytes AND 1) = 0 THEN FOR I = 0 TO h StartIdx = 2 TempNum = I * &H100& / h FOR J = 0 TO w Idx = J AND &HF
IF BaseLightnessMatrix(Idx, I AND &HF) >= TempNum THEN c = ct% ELSE c = cb%
FOR K = 0 TO 3 IF BitMaskInt(7 - K) AND c THEN TempInt(K) = TempInt(K) OR BitMaskInt(Idx) NEXT K
IF Idx = &HF OR J = w THEN Idx0 = StartIdx FOR K = 0 TO 3 MapArr(Idx0) = TempInt(K) Idx0 = Idx0 + ChanInts TempInt(K) = 0 NEXT K StartIdx = StartIdx + 1
END IF
NEXT J PUT (rct.Left, rct.Top + I), MapArr, PSET NEXT I
ELSE DIM TempArr(0 TO ChanInts - 1, 0 TO 1) AS INTEGER
FOR I = 0 TO h StartIdx = 2 Idx1 = 0 TempNum = I * &HFF& / h FOR J = 0 TO w Idx = J AND &HF
IF LightnessMatrix(Idx, I AND &HF) >= TempNum THEN c = ct% ELSE c = cb%
FOR K = 0 TO 3 IF BitMaskInt(7 - K) AND c THEN TempInt(K) = TempInt(K) OR BitMaskInt(Idx) NEXT K
IF Idx = &HF OR J = w THEN Idx0 = StartIdx FOR K = 0 TO 3 STEP 2 MapArr(Idx0) = TempInt(K) TempArr(Idx1, K / 2) = TempInt(K + 1) Idx0 = Idx0 + ChanBytes TempInt(K) = 0 TempInt(K + 1) = 0 NEXT K StartIdx = StartIdx + 1 Idx1 = Idx1 + 1
END IF
NEXT J Idx0 = VARSEG(MapArr(0)) Idx1 = VARPTR(MapArr(0)) Idx1 = Idx1 + 2 * 2 + ChanBytes MemCopy VARSEG(TempArr(0, 0)), VARPTR(TempArr(0, 0)), Idx0, Idx1, ChanBytes Idx1 = Idx1 + ChanBytes * 2 MemCopy VARSEG(TempArr(0, 1)), VARPTR(TempArr(0, 1)), Idx0, Idx1, ChanBytes PUT (rct.Left, rct.Top + I), MapArr, PSET NEXT I
END IF
END SUB
SUB InitBit DIM I AS INTEGER
FOR I = 0 TO 7 BitMaskInt(I) = 2 ^ (7 - I) NEXT I BitMaskInt(8) = &H8000 FOR I = 9 TO &HF BitMaskInt(I) = 2 ^ (&H17 - I) NEXT I
END SUB
SUB InitFont DIM I AS INTEGER, J AS INTEGER DIM TempPos AS INTEGER DIM TempByte AS INTEGER
SCREEN 12 WIDTH 80, 30
DEF SEG = &HA000 FOR I = 0 TO &HFF LINE (0, 0)-(&HF, &HF), 0, BF LOCATE 1, 1 PRINT CHR$(I) TempPos = 0 FOR J = 0 TO &HF TempByte = PEEK(TempPos) FontData(J, I) = MakeWord(0, TempByte) TempPos = TempPos + 80 '=640/8
NEXT J 'WHILE INKEY$ = "": WEND
NEXT I DEF SEG
TextC = 15 TextLf = True AutoLf = False TextStepX = 0 TextStepY = 0 CharAdd = CharWi LineAdd = CharHe
CLS
END SUB
SUB InitLightM DIM I AS INTEGER, J AS INTEGER, K AS INTEGER DIM TempStr AS STRING DIM TempNum AS INTEGER
FOR I = 0 TO &HF FOR J = 0 TO &HF READ TempStr TempNum = VAL("&H" + TempStr) BaseLightnessMatrix(I, J) = TempNum '这样做是为了简化运算,原来需要乘除运算(R*&H100/&HFF>L),现在只需要比较(R>=L),具体可看RGB12函数 IF TempNum <= &H7F THEN TempNum = TempNum + 1 LightnessMatrix(I, J) = TempNum
NEXT J NEXT I FOR I = 0 TO 1 'R FOR J = 0 TO 1 'G FOR K = 0 TO 1 'B RGBIndex(I, J, K) = I * 4 OR J * 2 OR K OR 8 NEXT K NEXT J NEXT I RGBIndex(0, 0, 0) = 0
END SUB
SUB InitMemCopy DIM ASMStr AS STRING ASMStr = "" ASMStr = ASMStr + CHR$(85) 'PUSH BP ASMStr = ASMStr + CHR$(137) + CHR$(229) 'MOV BP,SP ASMStr = ASMStr + CHR$(30) 'PUSH DS ASMStr = ASMStr + CHR$(139) + CHR$(70) + CHR$(10) 'MOV AX,[BP+0A] ASMStr = ASMStr + CHR$(142) + CHR$(192) 'MOV ES,AX ASMStr = ASMStr + CHR$(139) + CHR$(70) + CHR$(14) 'MOV AX,[BP+0E] ASMStr = ASMStr + CHR$(142) + CHR$(216) 'MOV DS,AX ASMStr = ASMStr + CHR$(139) + CHR$(118) + CHR$(12) 'MOV SI,[BP+0C] ASMStr = ASMStr + CHR$(139) + CHR$(126) + CHR$(8) 'MOV DI,[BP+08] ASMStr = ASMStr + CHR$(139) + CHR$(78) + CHR$(6) 'MOV CX,[BP+06] ASMStr = ASMStr + CHR$(243) 'REPZ ASMStr = ASMStr + CHR$(164) 'MOVSB ASMStr = ASMStr + CHR$(31) 'POP DS ASMStr = ASMStr + CHR$(93) 'POP BP ASMStr = ASMStr + CHR$(203) 'RETF 'PRINT LEN(ASMStr) 'STOP ASM.MemCopy = ASMStr END SUB
FUNCTION MakeWord% (LoByte AS INTEGER, HiByte AS INTEGER) MakeWord% = (LoByte AND &HFF) OR ((HiByte AND &H7F) * &H100) OR ((HiByte AND &H80) <> 0 AND &H8000) END FUNCTION
SUB MemCopy (fromseg%, fromoffset%, toseg%, tooffset%, bytes%) DEF SEG = VARSEG(ASM.MemCopy) CALL Absolute(BYVAL fromseg%, BYVAL fromoffset%, BYVAL toseg%, BYVAL tooffset%, BYVAL bytes%, VARPTR(ASM.MemCopy)) DEF SEG END SUB
SUB MoveRect (rct AS Rect, x%, y%) rct.Left = rct.Left + x% rct.Top = rct.Top + y% rct.Right = rct.Right + x% rct.Bottom = rct.Bottom + y% END SUB
SUB RectAddSize (rct AS Rect, xAdd AS INTEGER, yAdd AS INTEGER) rct.Right = rct.Right + xAdd rct.Bottom = rct.Bottom + yAdd
END SUB
FUNCTION RectIsNull% (rct AS Rect) RectIsNull% = (rct.Right <= rct.Left) OR (rct.Bottom <= rct.Top) END FUNCTION
FUNCTION RGB12% (x%, y%, R%, G%, B%) 'DIM L AS INTEGER 'L = LightnessMatrix(x% AND &HF, y% AND &HF) 'RGB12% = RGBIndex((R% >= L) AND 1, (G% >= L) AND 1, (B% >= L) AND 1) '稍微移一下效果比较好 RGB12% = RGBIndex((R% >= LightnessMatrix(x% AND &HF, y% AND &HF)) AND 1, (G% >= LightnessMatrix(x% + 1 AND &HF, y% AND &HF)) AND 1, (B% >= LightnessMatrix(x% AND &HF, y% + 1 AND &HF)) AND 1) END FUNCTION
SUB SetRect (rct AS Rect, x1%, y1%, x2%, y2%) rct.Left = x1% rct.Top = y1% rct.Right = x2% rct.Bottom = y2%
END SUB
SUB SetRectMinMax (rct AS Rect, MinX%, MinY%, MaxX%, MaxY%) IF rct.Left < MinX% THEN rct.Left = MinX% IF rct.Top < MinY% THEN rct.Top = MinY% IF rct.Right > MaxX% THEN rct.Right = MaxX% IF rct.Bottom > MaxY% THEN rct.Bottom = MaxY%
END SUB
SUB SetRectPos (rct AS Rect, x%, y%) IF x% <> RectNoNum THEN rct.Right = x% + rct.Right - rct.Left: rct.Left = x% IF y% <> RectNoNum THEN rct.Bottom = y% + rct.Bottom - rct.Top: rct.Top = y% END SUB
SUB SetRectSize (rct AS Rect, w%, h%) IF w% <> RectNoNum THEN rct.Right = rct.Left + w% IF h% <> RectNoNum THEN rct.Bottom = rct.Top + h%
END SUB
SUB SizeRect (rct AS Rect, x%, y%) rct.Left = rct.Left - x% rct.Top = rct.Top - y% rct.Right = rct.Right + x% rct.Bottom = rct.Bottom + y% END SUB
|