'=========================================================================== ' Subject: MANDELBROT VIEWING PROGRAM Date: 06-03-96 (20:04) ' Author: Douglas H. Lusher Code: QB, QBasic, PDS ' Origin: FidoNet QUIK_BAS Echo Packet: EGAVGA.ABC '=========================================================================== '> By now you should know that I have managed to do repeated zoom '> using my own method in the MODEX version. But I would love to '> see what you come up in this regard. 'Well, it's still somewhat rough, but here it is. 'You will have to begin by entering values and computing a 'starting screen. When you save a screen, the values are saved 'along with it. Then you can load the file, move the cursor 'around the image, change the size of the cursor, etc. When 'you decide what you want to magnify, just press ENTER. Once 'that image is made, you can save it, reload it in the left 'window and magnify part of it, etc. It would certainly be 'possible - it would be pretty easy, in fact - to make it so 'that you could press a key and see the cursor on the new 'image without having to reload it, but I just haven't gotten 'that far yet. I'm not sure I will, either, I need to start 'giving some time to other projects, I'm afraid. CONST PgUpKey = -73, PgDnKey = -81 CONST UpArrow = -72, DnArrow = -80 CONST LArrow = -75, RArrow = -77 CONST ENTER = 13, ESC = 27 DEFSNG A-Z Abort% = 0: Disp$ = "##.#######" NumColors% = 16: Maxdwell! = 150 Beginning: SCREEN 0: WIDTH 80 COLOR 7, 1: CLS PRINT "Mandlebrot Viewing Program" PRINT DO PRINT "Begin with a [F]ile or by entering [V]alues? (F/V) "; LOCATE , , 1 A$ = UCASE$(INPUT$(1)) SELECT CASE A$ CASE "F": PRINT A$ INPUT "Enter file name: ", FileName$ IF LEN(FileName$) THEN EXIT DO CASE "V": PRINT A$ GOSUB GetCoords: IF Range! <> 0 THEN EXIT DO CASE CHR$(27): PRINT END CASE ELSE BEEP END SELECT LOOP SCREEN 12 Size% = 304 CursSize% = Size% \ 4 TopMarg% = 12 LeftMarg% = 332 LINE (LeftMarg% - 1, TopMarg% - 1)-STEP(Size% + 1, Size% + 1), 8, B LeftMarg% = 4 LINE (LeftMarg% - 1, TopMarg% - 1)-STEP(Size% + 1, Size% + 1), 8, B SELECT CASE A$ CASE "F": GOSUB GetImageFromFile CASE "V": GOSUB GetImageFromValues END SELECT CursX% = LeftMarg%: CursY% = TopMarg% + Size% - 1 GOSUB ResizeCursorArray GOSUB DrawCursor LOCATE 25, 2: PRINT "Use the arrow keys to move the cursor around"; LOCATE 26, 2: PRINT "Use the PageUp & PageDn keys to resize the cursor"; LOCATE 27, 2: PRINT "Press Enter to magnify the area within the cursor"; DO DO WHILE LEN(INKEY$): LOOP CALL GetKeypress(Keycode%) SELECT CASE Keycode% CASE UpArrow Temp% = CursY% - 1 IF Temp% - CursSize% >= TopMarg% THEN GOSUB EraseCursor: CursY% = Temp%: GOSUB DrawCursor ELSE BEEP END IF CASE DnArrow Temp% = CursY% + 1 IF Temp% < TopMarg% + Size% THEN GOSUB EraseCursor: CursY% = Temp%: GOSUB DrawCursor ELSE BEEP END IF CASE LArrow Temp% = CursX% - 1 IF Temp% >= LeftMarg% THEN GOSUB EraseCursor: CursX% = Temp%: GOSUB DrawCursor ELSE BEEP END IF CASE RArrow Temp% = CursX% + 1 IF Temp% + CursSize% < LeftMarg% + Size% THEN GOSUB EraseCursor: CursX% = Temp%: GOSUB DrawCursor ELSE BEEP END IF CASE PgUpKey IF CursSize% < Size% \ 2 THEN GOSUB EraseCursor CursSize% = CursSize% + 1 GOSUB ResizeCursorArray GOSUB DrawCursor END IF CASE PgDnKey IF CursSize% > 5 THEN GOSUB EraseCursor CursSize% = CursSize% - 1 GOSUB ResizeCursorArray GOSUB DrawCursor END IF CASE ENTER Real! = Range! * ((CursX% - LeftMarg%) / Size%) + Real! Imag! = Range! * ((Size% - (CursY% - TopMarg%)) / Size%) + Imag! Range! = Range! * (CursSize% / Size%) LeftMarg% = 332 GOSUB GetImageFromValues GOTO Beginning CASE ESC EXIT DO END SELECT LOOP SCREEN 0: WIDTH 80 END GetImageFromFile: File% = FREEFILE OPEN FileName$ FOR BINARY AS #File% SEEK #File%, LOF(File%) - 11 GET #File%, , Real! GET #File%, , Imag! GET #File%, , Range! CLOSE #File% GOSUB ShowCoords CALL BLOADnPUT(LeftMarg%, TopMarg%, FileName$) RETURN GetImageFromValues: GOSUB ShowCoords LOCATE 25, 1: PRINT SPC(79); " "; LOCATE 26, 1: PRINT SPC(79); " "; LOCATE 27, 1: PRINT SPC(79); " "; LOCATE 26, 22: PRINT "Please wait while image is created..."; GOSUB CreateImage LOCATE 26, 1: PRINT SPC(79); " "; IF NOT Abort% THEN LOCATE 28, 1: INPUT "Enter file name: ", FileName$ IF LEN(FileName$) THEN LOCATE 28, 1: PRINT SPC(79); " "; X1% = LeftMarg%: Y1% = TopMarg% X2% = LeftMarg% + Size% - 1: Y2% = TopMarg% + Size% - 1 CALL GETnBSAVE(X1%, Y1%, X2%, Y2%, 12, FileName$) File% = FREEFILE OPEN FileName$ FOR BINARY AS #File% SEEK #File%, LOF(File%) + 1 PUT #File%, , Real! PUT #File%, , Imag! PUT #File%, , Range! CLOSE #File% END IF END IF RETURN GetCoords: DO PRINT "The value of Real! must be between -2 and +2." INPUT "Enter a value for Real!: ", Real! LOOP UNTIL Real! >= -2 AND Real! <= 2 DO PRINT "The value of Imag! must be between -2 and +2." INPUT "Enter a value for Imag!: ", Imag! LOOP UNTIL Imag! >= -2 AND Imag! <= 2 DO PRINT "The value of Range! must be between 0 and 4." INPUT "Enter a value for Range!: ", Range! LOOP UNTIL Range! >= 0 AND Range! <= 4 RETURN ResizeCursorArray: Bytes% = ((CursSize% \ 8) + 1) * (CursSize% + 1) * 4 + 4 REDIM CursArray%(Bytes% \ 2) RETURN DrawCursor: GET (CursX%, CursY% - CursSize%)-STEP(CursSize%, CursSize%), CursArray% LINE (CursX%, CursY%)-STEP(CursSize%, -CursSize%), 15, B Rl! = Range! * ((CursX% - LeftMarg%) / Size%) + Real! Ig! = Range! * ((Size% - (CursY% - TopMarg%)) / Size%) + Imag! Rg! = Range! * (CursSize% / Size%) R% = (TopMarg% + Size%) \ 16 + 2 LOCATE R%, 43: PRINT "FracX = "; USING Disp$; Rl!; LOCATE R% + 1, 43: PRINT "FracY = "; USING Disp$; Ig!; LOCATE R% + 2, 43: PRINT "Range = "; USING Disp$; Rg!; RETURN EraseCursor: PUT (CursX%, CursY% - CursSize%), CursArray%, PSET RETURN ShowCoords: R% = (TopMarg% + Size%) \ 16 + 2 C% = LeftMarg% \ 8 + 2 LOCATE R%, C%: PRINT "FracX = "; USING Disp$; Real!; LOCATE R% + 1, C%: PRINT "FracY = "; USING Disp$; Imag!; LOCATE R% + 2, C%: PRINT "Range = "; USING Disp$; Range!; RETURN CreateImage: highdwell = 0 Gap = Range / Size% AC = Real FOR X% = LeftMarg% TO LeftMarg% + Size% - 1 AC = AC + Gap BC = Imag FOR Y% = TopMarg% + Size% - 1 TO TopMarg% STEP -1 IF INKEY$ = CHR$(27) THEN Abort% = -1: EXIT FOR BC = BC + Gap AZ = 0 BZ = 0 Count% = 0 Size! = 0 WHILE (Size! < 4) AND (Count% < Maxdwell) Temp = AZ * AZ - BZ * BZ + AC BZ = 2 * AZ * BZ + BC AZ = Temp Size! = AZ * AZ + BZ * BZ Count% = Count% + 1 WEND IF (Count% < Maxdwell) AND (Count% > highdwell) THEN highdwell = Count% IF Count% <> Maxdwell THEN Culler% = Count% MOD (NumColors% - 1) + 1 PSET (X%, Y%), Culler% END IF NEXT IF Abort% THEN EXIT FOR NEXT RETURN SUB BLOADnPUT (X1%, Y1%, FileName$) Temp% = 0 File% = FREEFILE OPEN FileName$ FOR BINARY AS File% GET #File%, 6, Temp% CLOSE File% Bytes& = Temp% AND &HFFFF& REDIM Image%(Bytes& \ 2) DEF SEG = VARSEG(Image%(0)) BLOAD FileName$, VARPTR(Image%(0)) PUT (X1%, Y1%), Image% DEF SEG END SUB SUB GetKeypress (Keycode%) STATIC DO: Ky$ = INKEY$: LOOP UNTIL LEN(Ky$) Keycode% = ASC(Ky$): IF Keycode% = 0 THEN Keycode% = -ASC(MID$(Ky$, 2)) END SUB DEFSNG A-Z SUB GETnBSAVE (X1%, Y1%, X2%, Y2%, Mode%, FileName$) SELECT CASE Mode% CASE 1: BitsPerPixel% = 2: BitPlanes% = 1 CASE 2: BitsPerPixel% = 1: BitPlanes% = 1 CASE 7: BitsPerPixel% = 1: BitPlanes% = 4 CASE 8: BitsPerPixel% = 1: BitPlanes% = 4 CASE 9: BitsPerPixel% = 1: BitPlanes% = 4 'in SCREEN 9, if EGA memory < 64K then BitPlanes% = 2 CASE 11: BitsPerPixel% = 1: BitPlanes% = 1 CASE 12: BitsPerPixel% = 1: BitPlanes% = 4 CASE 13: BitsPerPixel% = 8: BitPlanes% = 1 CASE ELSE: ERROR 5 END SELECT X% = ABS(X2% - X1%) + 1 'number of pixel columns Y% = ABS(Y2% - Y1%) + 1 'number of pixel rows Bytes& = CLNG(((X% * BitsPerPixel%) + 7) \ 8) * Y% * BitPlanes% + 4 IF Bytes& > 65535 THEN ERROR 5 REDIM Image%(Bytes& \ 2) GET (X1%, Y1%)-(X2%, Y2%), Image% DEF SEG = VARSEG(Image%(0)) BSAVE FileName$, VARPTR(Image%(0)), Bytes& DEF SEG END SUB