fractsrc.doc

advertisement
The source code for Fractint is freely available.
Enhancements to it are appreciated. If you want to add something to
Fractint and join the Stone Soup Group, please do! To submit changes,
see "Contacting the Authors" in Fractint's online help.
Copyright Information:
======================
Some parts of the source are from the public domain and are not
copyrighted.
Some parts of the source bear explicit copyright notices from the
author and are subject to the conditions listed there by the author.
The remainder of the source (not already public domain, no explicit
author's copyright notice) is Copyright 1990, 1991 by the Stone Soup
Group
(a loosely associated and ever-growing group of fanatic programmers).
The source code may be copied freely and may be used in other programs
under the following conditions:
It may not be used in a commercial program which produces fractal
images.
Please credit the author (in general, credit Fractint and the Stone
Soup
Group) as the source of the code.
Distribution of modified versions of Fractint:
==============================================
If you enhance Fractint and want to distribute the results to others, the
preferred approach is to join the Stone Soup Group - send us your
enhancements and get your name in lights in future versions of Fractint.
We prefer that a modified Fractint executable program not be distributed
to
others, but understand that you might want to give copies to friends.
This
is permitted, under the following conditions:
o The modified executable has a different name than "fractint.exe".
o The distribution includes a full unmodified copy of the corresponding
original version of fraint.exe. (The easiest way is to copy
fraint.exe
to yournew.exe, then "pkzip -a fraint.exe newfract.exe" to add your
version, and perhaps add a read.me file to describe it.)
o The heading displayed by the modified program clearly indicates that
it is a non-standard release. E.g. you might change the heading to
say "Non-standard Fractint, Modified by John Doe".
o All author credits and distribution information in the online help
are unchanged (adding lines for your work is of course ok.)
The source code for a modified version of Fractint may not be
distributed.
(This is because we don't want any chance of confusion over which version
of a source file is the official release.)
Compiling Fractint:
===================
FRASRC.EXE includes the complete source code for FRACTINT (.C and .ASM).
Recognizing that not everyone HAS (or even wants) an assembler, much less
either MASM 5.1 or Turbo-ASM, which are the only two assemblers that the
authors are aware of that can handle these particular files, it also
contains
a complete set of .OBJ files from the assembler code,
The distributed source will not compile to exactly match the Fractint
release - it compiles with a different version number and heading.
The Microsoft 6.00A C compiler and Microsoft 5.1 assembler are used for
Fractint releases, so that is the one combination of compiler/assembler
which is pretty much guaranteed to handle FRACTINT in all of its various
mutations.
Given that several of FRACTINT's co-authors now prefer (or only have!)
alternate combinations, we have re-arranged the code to (usually) handle
several popular alternatives. In particular:
Microsoft C 6.00A and MASM 5.1:
------------------------------Just run MAKEFRAC.BAT, which invokes the Microsoft NMK utility using the
files FRACHELP.MAK, FRACTINT.MAK, and FRACTINT.LNK. Note that the
assembler
.OBJ files have been included in the .ZIP file, so that you don't really
need MASM unless you are going to modify one or more of them. If you ARE
going to modify one of the assembler files, note that the distributed
versions rely on some nifty features added to version 5.1 (like the
'.model
medium,c' option) and will not assemble under older versions of MASM
without
a LOT of work.
Note that C 6.00 (the original release) had some problems. We never used
it
for a Fractint release. If you don't have the fixed version (6.00A) you
should compile parser.c, loadfile.c, and calcfrac.c with no optimization,
using the /qc option. There might be other problems, those are the only
ones we're aware of...
Warning: FRACTINT.MAK uses C6.00A's most aggressive optimizations. It is
assumed there is no aliasing. See Microsoft's documentation on the /Oa
and /Oz options.
Microsoft C 5.1:
---------------Edit MAKEFRAC.BAT: comment out the two "nmk ..." lines and uncomment
the lines for C5.1. Then run MAKEFRAC.
Quick-C:
-------FRACTINT is just too big for the interactive Quick-C (QC) environment.
You have to use the command-line variant of Quick-C (QCL).
Edit MAKEFRAC.BAT: comment out the two "nmk ..." lines and uncomment
the lines for QuickC. Then run MAKEFRAC.
We're not sure all versions of QuickC work. 2.01 works as of
Fractint version 16. Depending on how much memory you have available,
you may have to manually compile some modules without the /O option.
Turbo-C, Turbo-C++ and TASM
--------------------------Sorry, Turbo-C fans, but since version 14.0, FRACTINT requires TC++.
The lack of initialized FAR arrays and structures just did the older
Turbo-C
product in. The *good* news is that some of the FRACTINT authors now
use Turbo-C++, so the odds of released FRACTINT distributions that do
not compile with Turbo products are lower than they used to be.
A FRACTINT.PRJ file is included for Turbo-C users.
With TC++ you'll have to do a manual step for the help system each time
you
create a new fractint.exe - see notes in next section.
Help System
===========
You'll need to set up the help files to get any online help from a
modified
version of Fractint.
For MSC users the MAKEFRAC.BAT file contains the necessary steps, you
don't
need to do anything special.
TC++ users should:
start by creating HC.EXE using the supplied HC.PRJ file
run "hc /c" to create the file FRACTINT.HLP
each time you create a new fractint.exe, afterward run "hc /a" to
append
FRACTINT.HLP to the new FRACTINT.EXE
You don't need to understand the rest of this section unless you have a
problem.
The source for Fractint's help is in the files HELP.SRC, HELP2.SRC,
HELP3.SRC,
HELP4.SRC, and HELP5.SRC. The format of these files is described in
HC.DOC.
The program HC.C ("help compiler") is used to convert the help text into
the form Fractint uses at run time.
Running "hc /c" compiles HELPx.SRC. It produces the file HELPDEFS.H for
use when compiling Fractint, and the file FRACTINT.HLP.
Running "hc /a" appends the FRACTINT.HLP file to FRACTINT.EXE to make the
compiled help info available at run time.
Overlays
========
Note: generally you won't have to worry about this!
Only the addition of huge code (new overlays), or work which changes the
relationship between major components of Fractint, are likely to affect
the overlay structure. However, if you make changes in a module which has
a
comment at the start saying it is an overlay, please follow the
guidelines
for use of ENTER_OVLY and EXIT_OVLY described after the next paragraph.
Fractint uses the Microsoft Link overlay feature, to reduce the runtime
memory required (which would otherwise exceed what DOS can give it.)
Some caution is required with overlays. Those source modules which are
part of an overlay have a comment to indicate this at the start. See the
fractint.lnk file for the current overlay structure.
Some notes about overlays:
o The obvious one: control should not switch to different overlays
frequently, else Fractint will become sluggish. If the overlay
structure
changes, a test from floppy disk with no disk caching is a good idea.
o The linker cannot detect indirect calls (e.g. thing=routinename;
(*thing)();) to an overlay. Routines in overlays should not be
called
indirectly, except from within the same overlay.
o The overlay manager logic (inserted by the linker) does handle calls
from within one overlay to another - the new overlay is brought in
from disk (displacing the old one in memory), when the subroutine
finishes the old overlay is brought back into memory.
o The overlay manager logic does not handle situations like the
following:
overlayA calls residentB(), which calls overlayC(). OverlayC is
loaded
and executed ok, eventually control returns to residentB ok, BUT the
return from there to overlayA does NOT reload overlayA! Fractint has
constructs called ENTER_OVLY and EXIT_OVLY to circumvent this
problem.
Guidelines for routines in overlayed modules:
o If the routine is local, declare it "static" to ensure this and to
make analysis of relationships among overlays easier.
o If the routine is called from external code (resident, or in another
overlay), the first executable line in the routine must be:
ENTER_OVLY(OVLY_XXX); /* XXX is the module name */
Each "return" from the routine (incl. the implicit one at the end)
must
be preceded by:
EXIT_OVLY;
o When creating a new overlay XXX, add a new OVLY_XXX value to
Fractint:
Fractint.h has a define for each OVLY_XXX value. Miscres.c has a
routine "restore_active_ovly" which needs a new line for OVLY_XXX.
The source module needs a dummy routine "xxx_overlay".
Where the Goodies are
=====================
It has come to our attention that people who have no interest in fractals
at all have been wandering through the FRACTINT source code just to get
at
some of the neat tricks buried therein. Here are a few hints as to where
to look:
FRACTINT.C - The main routine. Nothing special here.
FRACTINT.H - General Include file. Nothing special here, either.
FRACTYPE.H - Fractal type-specific Include file.
PROMPTS.C
- The full-screen prompting code (using support routines
in VIDEO.ASM)
CMDFILES.C - Command line and sstools.ini parsing.
FRACTALS.C, - Most of the fractal-specific code. If you want to know
CALCFRAC.C,
how a fractal is calculated, look in here. Specific
FRACSUBR.C speed-em-up support for special fractal types is in:
FRACSUBA.ASM
CALCMAND.ASM
- Mandelbrot/Julia set calculations.
NEWTON.ASM - Newton calculations
LORENZ.C
- Attractor fractals and IFS
JB.C
- "Julibrot" fractal type calculations
TESTPT.C
- "Roll-your-own" fractal routine
MPMATH_C.C, - Mark Peterson's "fast-math" support routines.
MPMATH_A.ASM,
(this stuff puts some of the routines supplied by your
FPU387.ASM,
favorite "C" compiler to shame!)
FPU087.ASM,
...
FMATH.H,
...
MPMATH.H
...
PARSER.C
- The "type=formula" formula parser routines
LSYS.C
- L-Systems code
VIDEO.ASM
- Assembler code containing all of the video routines
(setting up the video, reading/writing pixels, zoom-box
code, color-cycling, graphics-to-text "help" switch,
LOADMAP.C TARGA.C,
TARGA.H,
FR8514A.ASM TPLUS.C
TPLUS.H
TPLUS_A.ASM
HGCFRA.ASM DISKVID.C YOURVID.C -
... with help from the routines below for special adapters:
Load .map files.
TARGA Video Routines
...
8514/A Routines
Targa+ video routines
...
...
Hercules Video Routines
"DISK'RAM" video routines
"Roll-your-own" video routines
GENERAL.ASM - General assembler code having nothing to do with fractals.
Lots of the tricky stuff is in here, and many of the "C"
routines that perform tricky functions rely on support
code buried in here. In particular, this routine has the:
CPU, FPU Detectors
Keyboard routines
Mouse routines
Expanded memory routines
32-bit scaled integer multiply and divide routines
ENCODER.C GIFVIEW.C, DECODER.C,
TGAVIEW.C,
F16.C,
TARGA_LC.H
LOADFILE.C LOADFDOS.C
GIF Encoder routine.
GIF Decoder routines.
(including a TARGA-format decoder currently used only for
loading obsolete .tga format "Continuous Potential" files)
...
Loads the Fractint parameter info from a GIF file.
subroutines for DOS Fractint only
LINE3D.C,
3D.C
PLOT3D
- 3D manipulation routines
ROTATE.C
EDITPAL.C
- routines which "spin" the VGA video-DAC.
- palette-editing mode
HELP.C
INTRO.C
- HELP support
- title screen
ZOOM.C
- 3D subroutines for LINE3D.C and LORENZ.C
- Zoombox manipulation.
PRINTER.C, - The Printer Routines
PRINTERA.ASM
Data used by PRINTER.C
MISCRES.C
MISCOVL.C
REALDOS.C
PORT.H
- Miscellaneous resident subroutines; nothing special.
- Miscellaneous overlayed subroutines; includes <B>atch
command.
- Some subroutines isolated from Windows development work;
nothing special in here.
- Some portability stuff, nothing special here.
How things are set up
=====================
I've had to go through a lot of the code to figure out how things are set
up. These are my rough notes, which I'm including in case they can help
someone else. -- Ken Shirriff
The control flow is very confusing.
Here are some details:
Each fractal type has an entry in the fractalspecific table in
fractalp.c.
Entries that are not displayed are marked with an asterisk. Each entry
is
marked as int or not int, and either has a pointer to another entry
(tofloat) or NOFRACTAL. If you select float and the type is int or vice
versa, you will end up with the tofloat type. (e.g. If you select entry
MANDEL, and select floating point, you will get entry MANDELFP). There
are
also pointers tojulia and tomandel, which allow you to switch between
mandel
and julia. The four functions listed are curfractalspecific->orbitcalc,
curfractalspecific->per_pixel, curfractalspecific->per_image, and
curfractalspecific->calctype.
main calls calcfracinit.
calcfractint: this sets up curfractalspecific, which is the appropriate
entry
from the fractalspecific table. This routine does the int/float
conversion.
main calls calcfract, which calls timer, which calls perform_worklist
perform_worklist calls curfractalspecific->per_image, which is eg.
MandelSetup
MandelSetup: sets calctype to curfractalspecific->calctype, or for
special
cases (eg. decomposition) to StandardFractal
perform_worklist calls solidguess (or whatever drawing system)
solidguess calls *calctype for each pixel; calctype is eg.
StandardFractal
StandardFractal calls curfractalspecific->per_pixel once, and then loops
over
each iteration calling curfractalspecific->orbitcalc. These routines
are eg. mandel_per_pixel and JuliaFractal.
Here is the structure of the main routine:
main()
{
initialize things
restorestart:
if loading, look after specifying image
imagestart:
while (adapter<0) {
process keys from short main menu
}
while (1) {
if (calc_status != 2 || showfile==0) {
initialize videoentry from videotable[adapter]
initialize size, color, etc. from videoentry
setvideomode()
}
if (showfile==0) {
load file
}
calcfracinit();
save corners, zoom data
if (showfile != 0) {
calcfract(); /* calculates the fractal until interrupted */
}
resumeloop:
if (no key pressed) {
set keypress = 13 to continue
} else if (key pressed) {
check input key
} else if (batch mode) {
look after batch key
}
process key from long menu
}
}
How the video entries are managed:
get_video_mode(fractal_info): This routine is used to select a video mode
to match a picture we're loading. It loads vidtbl and then tries to
find a video mode that matches that in fractal_info. Asks the user
to
select one if there's no good match. Figures out how to reduce the
image
to fit the screen.
select_video_mode(curmode): This is the main-menu routine for the user to
pick a video mode. picks default video mode, lets user select mode
from menu, copies entry to videoentry, puts entry in videotable if
not
there, calls update_fractint_cfg if key reassigned, returns key
corresponding to mode
check_vidmode_key(option, keypress): if keypress corresponds to a
videomode in
videotable (for option 0) or vidtbl (for option 1) return the
videomode
index, else -1.
check_vidmode_keyname: converts ascii key name into key number
adapter_detect: checks for type of video (ega, cga, etc) and set
video_type,
mode7text, textsafe.
load_videotable: reads the entries in fractint.cfg into vidtbl
copies entries with an associated function key into videotable
load_fractint_cfg: reads video modes in fractint.cfg into vidtbl
(or copies from videotable) if fractint.cfg missing or bad
update_fractint_cfg: writes the entry in videoentry into the fractint.cfg
file.
vidtbl: contains the video modes from fractint.cfg
videotable: contains video modes with function keys; initialized in
video.asm
video_type: contains type: hgc, egc, cga, mcga
Here is how the floating point modes are set up.
parser.c uses the MathTypes:
D_MATH: uses double precision routines, such as dStkMul, and FPUsincos
This is used if we have a fpu.
M_MATH: uses MP type (mantissa, exponent). These routines such as
mStkAdd
call MPCadd, which call pMPadd, which calls MPadd086 or MPadd386.
The MP routines work on multiple precision, MPC works on complex
pairs
of multiple precision.
L_MATH: uses integer math. Routines such as lStkAdd.
Download