home *** CD-ROM | disk | FTP | other *** search
- 1 '
- 1 ' Tacky, hacky program to do Mandelbrot pretty color pictures
- 1 '
- 1 ' Some storage declarations
- 1 ' XOrigin Real part Origin
- 1 ' YOrigin Imaginary part origin
- 1 ' Iterations% Maximum number of iterations for each point
- 1 ' DeltaX Maximum X delta
- 1 ' DeltaY Maximum Y delta
- 1 ' X% Current X coordinate
- 1 ' Y% Current Y coordinate
- 1 ' XInc% X increment
- 1 ' YInc% Y increment
- 1 ' ScreenX% Screen X coordinate
- 1 ' ScreenY% Screen Y coordinate
- 1 ' MouseX Screen X coordinate of mouse origin
- 1 ' MouseY Screen Y coordinate of mouse origin
- 1 ' MouseDX Screen delta X for mouse box
- 1 ' Scale%() Current scaling array
- 1 ' Screen% An array to save the screen into
- 1 ' FileName$ The filename to write the screen into
- 1 ' Resolution% Screen resolution (0=320, 1=640)
- 1 ' BitPlanes% Number of bit planes to use
- 1 ' Prompt$ Command prompt string
- 1 ' Command$ Command string
- 1 ' Upper$ String of upper case characters
- 1 ' Lower$ String of lower case characters
- 1 ' LowerCase% Non-zero if lower case characters are ok from the command
- 1 ' Valid% Non-zero if the screen data is valid
- 1 ' MouseValid% Non-zero if the mouse data is valid
- 1 ' Default Default numeric argument
- 1 ' Result Numeric argument from keyboard
- 1 ' Direction% Sign of direction for UP/DOWN/LEFT/RIGHT
- 1 ' Code% Array containing iteration loop code
- 1 ' Regs% Array containing registers for LibCall
- 1 ' ContourValid% Non-zero if contouring array has been built
- 1 ' Boot% True if we're bootstrapping
- 1 '
- 1000 Dim Scale%(2000), Screen%(16010), Code%(150), Regs%(16)
- 1010 Upper$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- 1020 Lower$ = "abcdefghijklmnopqrstuvwxyz"
- 1030 Def FnMax(a%, b%) = a% - (a% < b%) * (b% - a%)
- 1035 Boot% = 0 ' Assume not booting
- 1 '
- 1 ' Read the initial mandelbrot set:
- 1 '
- 1040 FileName$ = "MandelSet.640"
- 1050 GoSub 13000 : If Success% Then GoTo 1100
- 1060 FileName$ = "MandelSet.320"
- 1070 GoSub 13000 : If Success% Then GoTo 1100
- 1075 XOrigin = -2.0 : YOrigin = -1.125 : DeltaX = 3.99 : DeltaY = DeltaX * 180 / 320
- 1076 Iterations% = 250 : Resolution% = 0 ' Default iterations and resolution
- 1077 BitPlanes% = 4 ' Default number of bit planes
- 1080 FileName$ = "MandelSet.320" ' Default bootstrap filename
- 1090 Boot% = -1 ' We're bootstrapping !
- 1 '
- 1 ' Read the iteration loop from disk:
- 1 '
- 1100 BLoad "MandelMung", VarPtr(Code%(0))
- 1 '
- 1 ' Zero all the regs:
- 1 '
- 1110 For I% = 0 to 15
- 1120 Regs%(I%) = 0
- 1130 Next I%
- 1140 ContourValid% = 0 ' Contour array isn't valid yet
- 1150 MouseValid% = 0 ' No valid mouse data yet
- 1 '
- 1 ' Setup the screen
- 1 '
- 2000 RGB 0, 0, 0, 0 ' Set color register zero to black
- 2010 RGB 1, 6, 9, 15 ' Set color register 1 to dark blue
- 2020 Screen Resolution%, BitPlanes%, 0 ' Setup screen resolution
- 2030 ScnClr ' Make sure the screen is clear
- 2040 If Boot% Then GoTo 6000 ' Compute set if in boot mode
- 2050 GShape (0, 0), Screen%() ' Restore the old screen data
- 2060 Valid% = 1 ' Say our data isn't valid
- 1 '
- 1 ' Look for some commands:
- 1 '
- 3000 GoSub 10000 ' Wait for the user to be ready
- 3010 GShape (0, 0), Screen% ' Restore the screen
- 3015 Prompt$ = "Command: " ' Get the command prompt
- 3020 LowerCase% = 0 ' Make sure everything's upper case
- 3025 GoSub 14000 ' Get the command string
- 3030 If Command$ = "EXIT" Then End
- 3035 If Command$ = "GO" Then GoTo 6000
- 3040 If Command$ = "SAVE" Then GoTo 3100
- 3045 If Command$ = "RESET" Then GoTo 1010
- 3050 If Command$ = "READ" Then GoTo 3200
- 3055 If Command$ = "CLEAR" Then GoTo 3500
- 3060 If Command$ = "SET" Then GoTo 3300
- 3065 If Command$ = "SHOW" Then GoTo 3400
- 3070 If Command$ = "UP" Then GoTo 3600
- 3075 If Command$ = "DOWN" Then GoTo 3610
- 3077 If Command$ = "RIGHT" Then GoTo 3700
- 3079 If Command$ = "LEFT" Then GoTo 3710
- 3080 If Command$ = "ZOOM" Then GoTo 3800
- 3085 If Command$ = "MOUSE" Then GoTo 4000
- 3090 If Command$ = "SYSTEM" Then System
- 3097 If Command$ = "HELP" Then GoTo 3900
- 3098 If Command$ = "" Then GoTo 3000
- 3099 Print at (0,0) "? Command error";: GoTo 3000
- 1 '
- 1 ' He wants to save something, prompt for the filename:
- 1 '
- 3100 If Valid% Then GoTo 3120 ' Only do this if screen active
- 3110 Print at (0,0) "? Data not computed";: GoTo 3000
- 3120 Prompt$ = "File name: " ' Ask him for a filename
- 3130 LowerCase% = 1 ' Say lowercase here is ok
- 3140 GoSub 14000 ' Go get the filename
- 3150 FileName$ = Command$ ' Copy the filename
- 3160 GoSub 12000 ' Go write the file
- 3165 Boot% = 0 ' We aren't booting anymore I guess
- 3170 If Success% Then GoTo 3010 ' Ok, go ask for another command
- 3180 Print at (0,0) "? File write error";
- 3190 GoTo 3000 ' Wait for the mouse again
- 1 '
- 1 ' He wants to read a file. Prompt for it:
- 1 '
- 3200 Prompt$ = "File name: " ' Ask him for a filename
- 3210 LowerCase% = 1 ' Say lowercase here is ok
- 3220 GoSub 14000 ' Ask for the filename
- 3230 FileName$ = Command$ ' Copy the filename
- 3240 GoSub 13000 ' Go read the file
- 3250 If Success% Then GoTo 2000 ' Re-init the screen if happy
- 3260 Print at (0,0) "? File read error - Reset";
- 3270 GoSub 10000 ' Wait for a mouse button
- 3280 GoTo 1010 ' And restart
- 1 '
- 1 ' Prompt the user for the new values:
- 1 '
- 3300 Prompt$ = "X Origin " : Default = XOrigin : GoSub 16000
- 3305 XOrigin = Result
- 3310 Prompt$ = "Y Origin " : Default = YOrigin : GoSub 16000
- 3315 YOrigin = Result
- 3320 Prompt$ = "Delta X " : Default = DeltaX : GoSub 16000
- 3325 DeltaX = Result : DeltaY = DeltaX * 180/320
- 3330 Prompt$ = "Iterations " : Default = Iterations% : GoSub 16000
- 3335 Iterations% = Result
- 3340 Prompt$ = "Resolution " : Default = Resolution% : GoSub 16000
- 3345 Resolution% = Result
- 3350 Prompt$ = "Bit Planes " : Default = BitPlanes% : GoSub 16000
- 3355 BitPlanes% = Result
- 3360 If ((Resolution% + BitPlanes%) < 6) And (Resolution% > -1) And (Resolution% < 2) And (BitPlanes% > 0) Then 3390
- 3370 Print at (0,0) "? Illegal resolution/bitplane values" : GoTo 3000
- 3390 GoTo 3880 ' Say the screen and mouse isn't valid
- 1 '
- 1 ' Show the current values:
- 1 '
- 3400 If MouseValid% = 0 Then Print at (0,0) "X Origin = "; XOrigin; " Y Origin = "; YOrigin
- 3405 If MouseValid% = 1 Then Print at (0,0) "X Origin = "; MouseX ; " Y Origin = "; MouseY
- 3410 If MouseValid% = 0 Then Print "Delta X = "; DeltaX; " Delta Y = "; DeltaY
- 3415 If MouseValid% = 1 Then Print "Delta X = "; MouseDX;" Delta Y = "; MouseDY
- 3420 Print "Iterations = "; Iterations%
- 3430 Print "Resolution = "; Resolution%
- 3450 Print " Bit Planes = "; BitPlanes%;
- 3460 GoTo 3000
- 1 '
- 1 ' Here if we want to clear the data just set. About the only thing that
- 1 ' can be done is default back to the current screen data
- 1 '
- 3500 GoSub 13500 ' Yank the data back from Screen%
- 3510 Valid% = 1 ' Say the screen's valid again
- 3520 GoTo 2000 ' Back to the prompt loop
- 1 '
- 1 ' Here if we want to increment Y some fraction of the screen:
- 1 '
- 3600 Direction% = 1 : GoTo 3620 ' Set sign of increment
- 1 '
- 1 ' Here if we want to decrement Y some fraction of the screen:
- 1 '
- 3610 Direction% = -1 ' Set the sign of the increment
- 3620 Prompt$ = "Screen fraction " ' Set the prompt
- 3630 Default = .5 ' Assume half the screen
- 3640 GoSub 16000 ' Read the screen fraction
- 3650 YOrigin = YOrigin + (DeltaY * Result * Direction%)
- 3660 GoTo 3880 ' Screen data not valid
- 1 '
- 1 ' Here if we want to increment X some fraction of the screen:
- 1 '
- 3700 Direction% = 1 : GoTo 3720 ' Set sign of the increment
- 1 '
- 1 ' Here if we want to decrement X some fraction of the screen:
- 1 '
- 3710 Direction% = -1 ' Set sign of the increment
- 3720 Prompt$ = "Screen fraction " ' Set the prompt
- 3730 Default = .5 ' Assume half the screen
- 3740 GoSub 16000 ' Read the screen fraction
- 3750 XOrigin = XOrigin + (DeltaX * Result * Direction%)
- 3760 GoTo 3880 ' Screen is no longer valid
- 1 '
- 1 ' If here we want to zoom in or out. > 1 is zoom in, < 1 is zoom out
- 1 '
- 3800 Prompt$ = "Zoom Factor " ' Set the prompt
- 3810 Default = 2 ' Assume twice resolution
- 3820 GoSub 16000 ' Get the zoom factor
- 3830 If Result > 0 Then GoTo 3860 ' Check range
- 3840 Print "? Must be greater than 0" ' Complain
- 3850 GoTo 3000 ' Let him think about it
- 3860 DeltaX = DeltaX / Result ' Scale the DeltaX
- 3870 DeltaY = DeltaY / Result ' Scale the DeltaY
- 3880 Valid% = 0 ' Screen's no longer valid
- 3885 MouseValid% = 0 ' No more mouse data
- 3890 GoTo 3010 ' Prompt again
- 1 '
- 1 ' Give some hint as to what we're about:
- 1 '
- 3900 Print at (0,0) "One of the following commands:"
- 3905 Print "Clear Clear data just set"
- 3910 Print "Down Reset Y origin downwards"
- 3915 Print "Exit Exit Mandelbrot.Bas"
- 3920 Print "Go Compute the new set"
- 3925 Print "Help Show this text"
- 3930 Print "Left Reset X origin left"
- 3933 Print "Mouse Use mouse to set origin"
- 3935 Print "Read Read a saved screen"
- 3940 Print "Reset Reset program"
- 3945 Print "Right Reset X origin right"
- 3950 Print "Save Save the screen"
- 3955 Print "Set Set new data"
- 3960 Print "Show Show current settings"
- 3965 Print "System Exit to CLI or workbench"
- 3970 Print "Up Reset Y origin upwards"
- 3975 Print "Zoom Zoom current settings"
- 3980 Print "Press left mouse button to continue"
- 3999 GoTo 3000
- 1 '
- 1 ' Here to set the new coordinates using the mouse:
- 1 '
- 4000 GoSub 20000 ' Go get the new coordinates
- 4010 Print at (0,0) "X = "; MouseX
- 4020 Print "Y = "; MouseY
- 4030 Print "DeltaX = "; MouseDX
- 4040 Print "DeltaY = "; MouseDY
- 4050 GoTo 3000
- 1 '
- 1 ' Main loop here:
- 1'
- 6000 If ContourValid%= 0 Then GoSub 11000 ' Compute the contour map
- 6001 If MouseValid% = 0 Then GoTo 6010 ' Skip this if mouse not valid
- 6002 XOrigin = MouseX : YOrigin = MouseY
- 6003 DeltaX = MouseDX : DeltaY = MouseDY
- 6010 Screen Resolution%, BitPlanes%, 0 ' Setup the screen resolution
- 6020 ScnClr ' And start with a clean screen
- 6023 XInc% = (2 ^ 30 * DeltaX / 320 / (Resolution% + 1))
- 6024 YInc% = (2 ^ 30 * DeltaY / 180) ' Compute increments
- 6030 Y% = YOrigin * (2 ^ 30) ' Set initial Y
- 6040 For ScreenY% = 179 to 0 Step -1 ' Outside loop is Y%
- 6050 X% = XOrigin * (2 ^ 30) ' Set initial X again
- 6060 For ScreenX% = 0 to (320 * (Resolution% + 1) - 1) Step 1
- 1 '
- 1 ' Initialize a single point's values:
- 1 '
- 6070 Regs%(0) = X% : Regs%(1) = Y%
- 6080 Regs%(2) = Iterations%
- 1 '
- 1 ' Per point loop:
- 1 '
- 6100 LibCall VarPtr(Code%(0)), 0, Regs%()
- 6110 I% = Peek_W(VarPtr(Regs%(2)) + 2) ' Get the iteration count
- 6120 If I% > (Iterations% - 1) Then GoTo 6300
- 1 '
- 1 ' Here if we bummed out. Plot the point
- 1 '
- 6200 Draw (ScreenX%, ScreenY%), Scale%(I% + 1)
- 1 '
- 1 ' Bump to the next point
- 1'
- 6300 X% = X% + XInc%
- 6310 Next ScreenX%
- 6320 Y% = Y% + YInc%
- 6330 Next ScreenY%
- 1 '
- 1 ' All done!
- 1 '
- 6340 Valid% = 1 ' Say we're valid again
- 6350 MouseValid% = 0 ' Mouse data isn't valid
- 6360 SShape (0, 0; (320 * (Resolution% + 1)) - 1, 199), Screen%
- 6370 If Boot% Then Goto 3160 Else GoTo 3000
- 1 '
- 1 ' Write the data file out and quit
- 1 '
- 7000 GoSub 10000 ' Wait for the mouse button
- 7010 GoSub 12000 ' Write the file out
- 7020 End ' End of proggie
- 1 '
- 1 ' Subroutine to wait for the mouse button to be pressed
- 1 '
- 10000 Ask Mouse X%, Y%, Button%
- 10010 If Button% = 0 Then GoTo 10000
- 10020 Return
- 1 '
- 1 ' Subroutine to fill in the scaling array given the number of bit planes
- 1 ' desired.
- 1 '
- 11000 Interval% = 1
- 11010 Print at (0,0) "Computing contouring array";
- 11020 I% = 1
- 11030 Color% = 1
- 11040 For J% = 1 to Interval%
- 11050 If I% <= 2000 Then Scale%(I%) = Color%
- 11060 I% = I% + 1
- 11070 Next J%
- 11080 If I% > 1000 Then GoTo 11130
- 11090 Color% = Color% + 1
- 11100 If Color% < (2 ^ BitPlanes%) Then 11040
- 11110 Interval% = Interval% + 2
- 11120 GoTo 11030
- 11130 ContourValid% = 1 ' So we don't have to do this again
- 11140 Return
- 1 '
- 1 ' The disk file is created/read with BSAVE/BLOAD into array Screen%.
- 1 ' The first elements of this array are obtained from/fed to SShape/GShape.
- 1 ' We load values into this array following the screen data itself. On
- 1 ' write, the location in the array is determined by the resolution we're
- 1 ' writing. When reading the file, the offset can be obtained from the
- 1 ' resolution implied by the width paramter in the front of the array.
- 1 '
- 1 ' The values appended to the screen array are:
- 1 '
- 1 ' Byte # Contents
- 1 ' ==== = ========
- 1 ' 0 File format version number (1)
- 1 ' 1 Screen resolution mode (0 or 1)
- 1 ' 2-3 Iteration count
- 1 ' 4-7 X Origin
- 1 ' 8-11 Y Origin
- 1 ' 12-15 Delta X
- 1 ' 16-19 Delta Y
- 1 '
- 12000 SShape (0, 0; (320 * (Resolution% + 1) - 1), 199), Screen%()
- 12010 I% = (2000 * BitPlanes% * (Resolution% + 1)) + 2
- 12020 Poke VarPtr(Screen%(I%)), 2
- 12030 Poke VarPtr(Screen%(I%))+1, Resolution%
- 12040 Poke_W VarPtr(Screen%(I%))+2, Iterations%
- 12050 Screen%(I%+1) = Peek_L(VarPtr(XOrigin))
- 12060 Screen%(I%+2) = Peek_L(VarPtr(YOrigin))
- 12070 Screen%(I%+3) = Peek_L(VarPtr(DeltaX))
- 12080 Screen%(I%+4) = Peek_L(VarPtr(DeltaY))
- 12090 Success% = 0 : On Error GoTo 12130 ' In case of errors
- 12100 BSave FileName$, Varptr(Screen%(0)), (I% + 5) * 4
- 12110 Success% = 1 : On Error GoTo 0
- 12120 Return
- 12130 Resume 12120
- 1 '
- 1 ' Converse of the previous routine, this routine restores a screen to
- 1 ' memory. See the previous subroutine for notes on the file format.
- 1 '
- 13000 Success% = 0 : On Error GoTo 13660 ' In case the file lookup fails
- 13010 BLoad FileName$, VarPtr(Screen%(0))
- 13020 On Error GoTo 0
- 13500 BitPlanes% = Peek_W(VarPtr(Screen%(0)))
- 13510 Width% = Peek_W(VarPtr(Screen%(0))+2)
- 13520 If Width% < 320 Then Resolution% = 0 Else Resolution% = 1
- 13530 I% = (2000 * BitPlanes% * (Resolution% + 1)) + 2
- 13540 FileVersion% = Peek(VarPtr(Screen%(I%)))
- 13550 If (FileVersion% > 0) And (FileVersion% < 3) Then GoTo 13580
- 13560 Print "? File version number error"
- 13570 Return
- 13580 If FileVersion% < 2 Then Iterations% = Peek(VarPtr(Screen%(I%))+2)
- 13590 If FileVersion% >= 2 Then Iterations% = Peek_W(VarPtr(Screen%(I%))+2)
- 13600 Poke_L VarPtr(XOrigin), Peek_L(VarPtr(Screen%(I%+1)))
- 13610 Poke_L VarPtr(YOrigin), Peek_L(VarPtr(Screen%(I%+2)))
- 13620 Poke_L VarPtr(DeltaX), Peek_L(VarPtr(Screen%(I%+3)))
- 13630 Poke_L VarPtr(DeltaY), Peek_L(VarPtr(Screen%(I%+4)))
- 13640 Success% = 1
- 13650 Return
- 13660 Resume 13650
- 1 '
- 1 ' Subroutine to prompt for and read a command. Called with the command
- 1 ' prompt in Prompt$, and returns the command keyword (uppercased) in
- 1 ' Command$. We'll restore the screen after we're done.
- 1 '
- 14000 Print at (0,0) Prompt$;
- 14010 Input "", Command$
- 14020 GShape (0, 0), Screen% ' Restore the screen
- 14030 If LowerCase% Then Return ' Return now if lower case is ok
- 1 '
- 1 ' Subroutine to uppercase the alpha characters in the command string.
- 1 '
- 15000 For I% = 1 to Len(Command$)
- 15010 J% = InStr(1, Lower$, Mid$(Command$, I%, 1))
- 15030 If J% Then Replace$(Command$, I%, 1) = Mid$(Upper$, J%, 1)
- 15040 Next I%
- 15050 Return
- 1 '
- 1 ' Prompt for a numeric argument, preserving the old value if appropriate
- 1 '
- 16000 Prompt$ = Prompt$ + "(" + Str$(Default) + "): "
- 16010 GoSub 14000 ' Go prompt and read the number
- 16020 If Command$ = "" Then Result = Default Else Result = Val(Command$)
- 16030 Return
- 1 '
- 1 ' Routine to take new coordinates from mouse input.
- 1 ' User positions mouse to lower left corner of intended
- 1 ' area to zoom, clicks mouse button once. Position mouse
- 1 ' to upper left corner, click mouse button again. This
- 1 ' goes to great lengths to preserve the proper aspect
- 1 ' ratio.
- 1 '
- 20000 PenA 1 ' Set the default writing color
- 20005 XoverY = 320 * (Resolution% + 1) / 180 : YoverX = 1 / XoverY
- 1 '
- 1 ' Wait for the button to be pressed while on screen
- 1 '
- 20010 Ask Mouse X%, Y%, Button% ' Go read the mouse
- 20020 If X% < 0 or Y% < 0 Then GoTo 20010 ' Ignore if not in window
- 20030 If X% > ((Resolution% + 1) * 320) - 1 Then GoTo 20010
- 20040 If Y% > 179 Then GoTo 20010 ' Ignore if too big also
- 20050 If Button% = 0 Then GoTo 20010 ' Wait for mouse buttom
- 20060 MouseX% = X% : MouseY% = Y% : NewDX% = 0 : OldDX% = 0
- 1 '
- 1 ' Wait for the button to be released
- 1 '
- 20070 While Button% <> 0: Ask Mouse X%, Y%, Button%: Wend
- 1 '
- 1 ' Loop here waiting for the second pressing of the button
- 1 '
- 20080 While Button% = 0
- 20090 If X% < MouseX% Then GoTo 20210 ' Don't make negative boxes
- 20100 If Y% > MouseY% Then GoTo 20210
- 20110 If X% > ((Resolution% + 1) * 320) -1 Then GoTo 20210
- 20120 If Y% > 179 Then GoTo 20210 ' Don't bother if too big
- 20130 OldDX% = NewDX% ' Copy the old delta X
- 20140 NewDX% = FnMax ((X% - MouseX%), int(XoverY * (MouseY% - Y%)))
- 20150 If NewDX% = OldDX% Then GoTo 20210 ' Don't bother if no change
- 20160 GShape (0, 0), Screen% ' Something moved, restore the old screen
- 20170 X% = MouseX% + NewDX% ' Find the corner
- 20180 Y% = MouseY% - int(YoverX * NewDX%) ' of the box
- 20190 Draw (MouseX%, MouseY% to X%, MouseY% to X%, Y%), 1
- 20200 Draw (X%, Y% to MouseX%, Y% to MouseX%, MouseY%), 1
- 20210 Ask Mouse X%, Y%, Button% ' Get the new mouse position
- 20220 Wend
- 20230 MouseValid% = 1 ' Say we have valid mouse data
- 20240 Gshape (0, 0), Screen% ' Restore the screen
- 20250 MouseX = XOrigin + DeltaX * MouseX% / (320 * (Resolution% + 1))
- 20260 MouseY = YOrigin + (DeltaX * 180 / 320) * (179 - MouseY%) / 180
- 20270 MouseDX = DeltaX * NewDX% / (320 * (Resolution% + 1))
- 20280 MouseDY = MouseDX * 180 / 320
- 20290 Return
-
-
-
-