📄 miscfrac.c
字号:
/*
Miscellaneous fractal-specific code (formerly in CALCFRAC.C)
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <float.h>
#ifndef XFRACT
#include <dos.h>
#endif
#include <limits.h>
#include "fractint.h"
#include "fractype.h"
#include "mpmath.h"
#include "targa_lc.h"
#include "prototyp.h"
/* routines in this module */
static void set_Plasma_palette(void);
static U16 _fastcall adjust(int xa,int ya,int x,int y,int xb,int yb);
static void _fastcall subDivide(int x1,int y1,int x2,int y2);
static int _fastcall new_subD (int x1,int y1,int x2,int y2, int recur);
static void verhulst(void);
static void Bif_Period_Init(void);
static int _fastcall Bif_Periodic(int);
static void set_Cellular_palette(void);
U16 (_fastcall *getpix)(int,int) = (U16(_fastcall *)(int,int))getcolor;
extern int resuming;
extern char stdcalcmode;
extern int color, oldcolor, row, col, passes;
extern int ixstart, ixstop, iystart, iystop;
extern _CMPLX init,tmp,old,new,saved;
extern _CMPLX parm,parm2;
extern double far *dx0, far *dy0;
extern double far *dx1, far *dy1;
extern long far *lx0, far *ly0;
extern long far *lx1, far *ly1;
extern long delx, dely;
extern double deltaX, deltaY;
extern int sxoffs, syoffs, sxdots, sydots;
extern int xdots, ydots;
extern int maxit, inside, colors, andcolor, dotmode;
extern double param[];
extern int rflag, rseed;
extern int pot16bit, potflag;
extern int diskvideo;
extern int bitshift;
extern long fudge;
extern int show_orbit;
extern int periodicitycheck, integerfractal;
extern _LCMPLX linit;
extern _LCMPLX ltmp;
extern _LCMPLX lold,lnew,lparm,lparm2;
extern long ltempsqrx,ltempsqry;
extern double tempsqrx,tempsqry;
extern int overflow;
extern int kbdcount, max_kbdcount;
extern int reset_periodicity;
extern int calc_status;
extern int iterations, invert;
extern int save_release;
extern int LogFlag;
extern int (calctype());
extern int realcolor;
extern int nxtscreenflag;
extern double magnitude, rqlim, rqlim2, rqlim_save;
extern long lmagnitud, llimit, llimit2, lclosenuff, l16triglim;
extern int orbit_color, orbit_ptr, showdot;
extern int debugflag;
#ifndef XFRACT
extern char dstack[4096];
extern char boxy[4096];
#else
BYTE dstack[4096];
#endif
typedef void (_fastcall *PLOT)(int,int,int);
/***************** standalone engine for "test" ********************/
int test()
{
int startrow,startpass,numpasses;
startrow = startpass = 0;
if (resuming)
{
start_resume();
get_resume(sizeof(int),&startrow,sizeof(int),&startpass,0);
end_resume();
}
if(teststart()) /* assume it was stand-alone, doesn't want passes logic */
return(0);
numpasses = (stdcalcmode == '1') ? 0 : 1;
for (passes=startpass; passes <= numpasses ; passes++)
{
for (row = startrow; row <= iystop; row=row+1+numpasses)
{
register int col;
for (col = 0; col <= ixstop; col++) /* look at each point on screen */
{
register color;
init.y = dy0[row]+dy1[col];
init.x = dx0[col]+dx1[row];
if(check_key())
{
testend();
alloc_resume(20,1);
put_resume(sizeof(int),&row,sizeof(int),&passes,0);
return(-1);
}
color = testpt(init.x,init.y,parm.x,parm.y,maxit,inside);
if (color >= colors) /* avoid trouble if color is 0 */
if (colors < 16)
color &= andcolor;
else
color = ((color-1) % andcolor) + 1; /* skip color zero */
(*plot)(col,row,color);
if(numpasses && (passes == 0))
(*plot)(col,row+1,color);
}
}
startrow = passes + 1;
}
testend();
return(0);
}
/***************** standalone engine for "plasma" ********************/
static int iparmx; /* iparmx = parm.x * 16 */
static int shiftvalue; /* shift based on #colors */
extern int max_colors;
static int recur1=1;
static int pcolors;
static int recur_level = 0;
U16 max_plasma;
/* returns a random 16 bit value that is never 0 */
U16 rand16()
{
U16 value;
value = rand15();
value <<= 1;
value += rand15()&1;
if(value < 1)
value = 1;
return(value);
}
void _fastcall putpot(int x, int y, U16 color)
{
if(color < 1)
color = 1;
putcolor(x, y, color >> 8 ? color >> 8 : 1); /* don't write 0 */
/* we don't write this if dotmode==11 because the above putcolor
was already a "writedisk" in that case */
if (dotmode != 11)
writedisk(x+sxoffs,y+syoffs,color >> 8); /* upper 8 bits */
writedisk(x+sxoffs,y+sydots+syoffs,color&255); /* lower 8 bits */
}
U16 _fastcall getpot(int x, int y)
{
U16 color;
color = (U16)readdisk(x+sxoffs,y+syoffs);
color = (color << 8) + (U16) readdisk(x+sxoffs,y+sydots+syoffs);
return(color);
}
typedef struct palett
{
BYTE red;
BYTE green;
BYTE blue;
}
Palettetype;
extern Palettetype dacbox[256];
static int plasma_check; /* to limit kbd checking */
static U16 _fastcall adjust(int xa,int ya,int x,int y,int xb,int yb)
{
S32 pseudorandom;
pseudorandom = ((S32)iparmx)*((rand15()-16383));
/* pseudorandom = pseudorandom*(abs(xa-xb)+abs(ya-yb));*/
pseudorandom = pseudorandom * recur1;
pseudorandom = pseudorandom >> shiftvalue;
pseudorandom = (((S32)getpix(xa,ya)+(S32)getpix(xb,yb)+1)>>1)+pseudorandom;
if(max_plasma == 0)
{
if (pseudorandom >= pcolors)
pseudorandom = pcolors-1;
}
else if (pseudorandom >= max_plasma)
pseudorandom = max_plasma;
if(pseudorandom < 1)
pseudorandom = 1;
plot(x,y,(U16)pseudorandom);
return((U16)pseudorandom);
}
static int _fastcall new_subD (int x1,int y1,int x2,int y2, int recur)
{
int x,y;
int nx1;
int nx;
int ny1, ny;
S32 i, v;
struct sub {
BYTE t; /* top of stack */
int v[16]; /* subdivided value */
BYTE r[16]; /* recursion level */
};
static struct sub subx, suby;
/*
recur1=1;
for (i=1;i<=recur;i++)
recur1 = recur1 * 2;
recur1=320/recur1;
*/
recur1 = 320L >> recur;
suby.t = 2;
ny = suby.v[0] = y2;
ny1 = suby.v[2] = y1;
suby.r[0] = suby.r[2] = 0;
suby.r[1] = 1;
y = suby.v[1] = (ny1 + ny) >> 1;
while (suby.t >= 1)
{
if ((++plasma_check & 0x0f) == 1)
if(check_key())
{
/* naah, we don't want to flush this key!!!
getch();
*/
plasma_check--;
return(1);
}
while (suby.r[suby.t-1] < recur)
{
/* 1. Create new entry at top of the stack */
/* 2. Copy old top value to new top value. */
/* This is largest y value. */
/* 3. Smallest y is now old mid point */
/* 4. Set new mid point recursion level */
/* 5. New mid point value is average */
/* of largest and smallest */
suby.t++;
ny1 = suby.v[suby.t] = suby.v[suby.t-1];
ny = suby.v[suby.t-2];
suby.r[suby.t] = suby.r[suby.t-1];
y = suby.v[suby.t-1] = (ny1 + ny) >> 1;
suby.r[suby.t-1] = (int)max(suby.r[suby.t], suby.r[suby.t-2])+1;
}
subx.t = 2;
nx = subx.v[0] = x2;
nx1 = subx.v[2] = x1;
subx.r[0] = subx.r[2] = 0;
subx.r[1] = 1;
x = subx.v[1] = (nx1 + nx) >> 1;
while (subx.t >= 1)
{
while (subx.r[subx.t-1] < recur)
{
subx.t++; /* move the top ofthe stack up 1 */
nx1 = subx.v[subx.t] = subx.v[subx.t-1];
nx = subx.v[subx.t-2];
subx.r[subx.t] = subx.r[subx.t-1];
x = subx.v[subx.t-1] = (nx1 + nx) >> 1;
subx.r[subx.t-1] = (int)max(subx.r[subx.t],
subx.r[subx.t-2])+1;
}
if ((i = getpix(nx, y)) == 0)
i = adjust(nx,ny1,nx,y ,nx,ny);
v = i;
if ((i = getpix(x, ny)) == 0)
i = adjust(nx1,ny,x ,ny,nx,ny);
v += i;
if(getpix(x,y) == 0)
{
if ((i = getpix(x, ny1)) == 0)
i = adjust(nx1,ny1,x ,ny1,nx,ny1);
v += i;
if ((i = getpix(nx1, y)) == 0)
i = adjust(nx1,ny1,nx1,y ,nx1,ny);
v += i;
plot(x,y,(U16)((v + 2) >> 2));
}
if (subx.r[subx.t-1] == recur) subx.t = subx.t - 2;
}
if (suby.r[suby.t-1] == recur) suby.t = suby.t - 2;
}
return(0);
}
static void _fastcall subDivide(int x1,int y1,int x2,int y2)
{
int x,y;
S32 v,i;
if ((++plasma_check & 0x7f) == 1)
if(check_key())
{
plasma_check--;
return;
}
if(x2-x1<2 && y2-y1<2)
return;
recur_level++;
recur1 = 320L >> recur_level;
x = (x1+x2)>>1;
y = (y1+y2)>>1;
if((v=getpix(x,y1)) == 0)
v=adjust(x1,y1,x ,y1,x2,y1);
i=v;
if((v=getpix(x2,y)) == 0)
v=adjust(x2,y1,x2,y ,x2,y2);
i+=v;
if((v=getpix(x,y2)) == 0)
v=adjust(x1,y2,x ,y2,x2,y2);
i+=v;
if((v=getpix(x1,y)) == 0)
v=adjust(x1,y1,x1,y ,x1,y2);
i+=v;
if(getpix(x,y) == 0)
plot(x,y,(U16)((i+2)>>2));
subDivide(x1,y1,x ,y);
subDivide(x ,y1,x2,y);
subDivide(x ,y ,x2,y2);
subDivide(x1,y ,x ,y2);
recur_level--;
}
int plasma()
{
int i,k, n;
U16 rnd[4];
int OldPotFlag, OldPot16bit;
plasma_check = 0;
if(colors < 4) {
static char far plasmamsg[]={
"\
Plasma Clouds can currently only be run in a 4-or-more-color video\n\
mode (and color-cycled only on VGA adapters [or EGA adapters in their\n\
640x350x16 mode])." };
stopmsg(0,plasmamsg);
return(-1);
}
iparmx = param[0] * 8;
if (parm.x <= 0.0) iparmx = 16;
if (parm.x >= 100) iparmx = 800;
if ((!rflag) && param[2] == 1)
--rseed;
if (param[2] != 0 && param[2] != 1)
rseed = param[2];
max_plasma = (U16)param[3]; /* max_plasma is used as a flag for potential */
if(max_plasma != 0)
{
if (pot_startdisk() >= 0)
{
max_plasma = (U16)(1L << 16) -1;
plot = (PLOT)putpot;
getpix = getpot;
OldPotFlag = potflag;
OldPot16bit = pot16bit;
}
else
{
max_plasma = 0; /* can't do potential (startdisk failed) */
param[3] = 0;
plot = putcolor;
getpix = (U16(_fastcall *)(int,int))getcolor;
}
}
else
{
plot = putcolor;
getpix = (U16(_fastcall *)(int,int))getcolor;
}
srand(rseed);
if (!rflag) ++rseed;
if (colors == 256) /* set the (256-color) palette */
set_Plasma_palette(); /* skip this if < 256 colors */
if (colors > 16)
shiftvalue = 18;
else
{
if (colors > 4)
shiftvalue = 22;
else
{
if (colors > 2)
shiftvalue = 24;
else
shiftvalue = 25;
}
}
if(max_plasma != 0)
shiftvalue = 10;
if(max_plasma == 0)
{
pcolors = min(colors, max_colors);
for(n = 0; n < 4; n++)
rnd[n] = 1+(((rand15()/pcolors)*(pcolors-1))>>(shiftvalue-11));
}
else
for(n = 0; n < 4; n++)
rnd[n] = rand16();
plot( 0, 0, rnd[0]);
plot(xdots-1, 0, rnd[1]);
plot(xdots-1,ydots-1, rnd[2]);
plot( 0,ydots-1, rnd[3]);
recur_level = 0;
if (param[1] == 0)
subDivide(0,0,xdots-1,ydots-1);
else
{
recur1 = i = k = 1;
while(new_subD(0,0,xdots-1,ydots-1,i)==0)
{
k = k * 2;
if (k >(int)max(xdots-1,ydots-1))
break;
if (check_key())
{
n = 1;
goto done;
}
i++;
}
}
if (! check_key())
n = 0;
else
n = 1;
done:
if(max_plasma != 0)
{
potflag = OldPotFlag;
pot16bit = OldPot16bit;
}
plot = putcolor;
getpix = (U16(_fastcall *)(int,int))getcolor;
return(n);
}
static void set_Plasma_palette()
{
extern char far *mapdacbox;
static Palettetype Red = {
63, 0, 0 };
static Palettetype Green = {
0,63, 0 };
static Palettetype Blue = {
0, 0,63 };
int i;
if (mapdacbox) return; /* map= specified */
dacbox[0].red = 0 ;
dacbox[0].green= 0 ;
dacbox[0].blue = 0 ;
for(i=1;i<=85;i++)
{
dacbox[i].red = (i*Green.red + (86-i)*Blue.red)/85;
dacbox[i].green = (i*Green.green + (86-i)*Blue.green)/85;
dacbox[i].blue = (i*Green.blue + (86-i)*Blue.blue)/85;
dacbox[i+85].red = (i*Red.red + (86-i)*Green.red)/85;
dacbox[i+85].green = (i*Red.green + (86-i)*Green.green)/85;
dacbox[i+85].blue = (i*Red.blue + (86-i)*Green.blue)/85;
dacbox[i+170].red = (i*Blue.red + (86-i)*Red.red)/85;
dacbox[i+170].green = (i*Blue.green + (86-i)*Red.green)/85;
dacbox[i+170].blue = (i*Blue.blue + (86-i)*Red.blue)/85;
}
SetTgaColors(); /* TARGA 3 June 89 j mclain */
spindac(0,1);
}
/***************** standalone engine for "diffusion" ********************/
#define RANDOM(x) (rand()%(x))
/* This constant assumes that rand() returns a value from 0 to 32676 */
#define FOURPI (long)(4*PI*(double)(1L << 16))
int diffusion()
{
int xmax,ymax,xmin,ymin; /* Current maximum coordinates */
int border; /* Distance between release point and fractal */
int mode; /* Determines diffusion type: 0 = central (classic) */
/* 1 = falling particles */
/* 2 = square cavity */
int i;
double cosine,sine,angle;
long lcosine,lsine;
int x,y;
float r, radius, f_tmp;
extern char floatflag;
if (diskvideo)
notdiskmsg();
bitshift = 16;
fudge = 1L << 16;
border = param[0];
mode = param[1];
if (mode > 2)
mode=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -