mirror of
https://github.com/cc65/cc65.git
synced 2024-09-30 08:57:49 +00:00
363 lines
8.8 KiB
C
363 lines
8.8 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <cc65.h>
|
|
#include <conio.h>
|
|
#include <ctype.h>
|
|
#include <modload.h>
|
|
#include <tgi.h>
|
|
|
|
char buf[100]; // for ftostr
|
|
char buf2[100]; // for ftostr
|
|
char buf3[100]; // for ftostr
|
|
|
|
|
|
#ifndef DYN_DRV
|
|
# define DYN_DRV 1
|
|
#endif
|
|
|
|
#define COLOR_BACK TGI_COLOR_BLACK
|
|
#define COLOR_FORE TGI_COLOR_WHITE
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Data */
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
/* Driver stuff */
|
|
static unsigned MaxX;
|
|
static unsigned MaxY;
|
|
static unsigned AspectRatio;
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Code */
|
|
/*****************************************************************************/
|
|
|
|
static void CheckError (const char* S)
|
|
{
|
|
unsigned char Error = tgi_geterror ();
|
|
|
|
if (Error != TGI_ERR_OK) {
|
|
printf ("%s: %u\n", S, Error);
|
|
if (doesclrscrafterexit ()) {
|
|
cgetc ();
|
|
}
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
#if DYN_DRV
|
|
static void DoWarning (void)
|
|
/* Warn the user that the dynamic TGI driver is needed for this program */
|
|
{
|
|
printf ("Warning: This program needs the TGI\n"
|
|
"driver on disk! Press 'y' if you have\n"
|
|
"it - any other key exits.\n");
|
|
if (tolower (cgetc ()) != 'y') {
|
|
exit (EXIT_SUCCESS);
|
|
}
|
|
printf ("OK. Please wait patiently...\n");
|
|
}
|
|
#endif
|
|
|
|
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLUE };
|
|
|
|
#if 1
|
|
int XRes, YRes;
|
|
float xf, xfMin, xfMax, xfDelta, yf, yfMin, yfMax, yfDelta;
|
|
float radiusf, zf, zScale;
|
|
int x,y;
|
|
// unsigned char YMax;
|
|
int YMax;
|
|
unsigned int XResHalf;
|
|
float yfMinSquare;
|
|
|
|
float yfD;
|
|
float a;
|
|
float b;
|
|
float yfSquare;
|
|
|
|
int xoff = 0;
|
|
int yoff = 0;
|
|
|
|
void Dosincos(void) {
|
|
#if 1
|
|
tgi_setpalette (Palette);
|
|
tgi_setcolor (COLOR_FORE);
|
|
tgi_clear ();
|
|
#endif
|
|
/* Get stuff from the graph lib */
|
|
XRes = tgi_getmaxx() + 1;
|
|
// XRes = 320;
|
|
YRes = tgi_getmaxy() + 1;
|
|
// YRes = 200;
|
|
YMax = YRes - 1;
|
|
|
|
|
|
|
|
/* Compute and draw a 3d function. */
|
|
yfMin = -144.0f;
|
|
yfMax = 144.0f;
|
|
yf = 0;
|
|
// printf("yf:%s\n", _ftostr(buf, yf));
|
|
// printf("min:%s\n", _ftostr(buf, yfMin));
|
|
// printf("max:%s\n", _ftostr(buf, yfMax));
|
|
|
|
yfDelta = 2.25f;
|
|
zScale = -10.0f;
|
|
|
|
XResHalf = XRes * 0.5f;
|
|
yfMinSquare = yfMin * yfMin;
|
|
|
|
yoff = 20;
|
|
xoff = 0;
|
|
|
|
// for( yf = yfMin; yf < yfMax; yf += yfDelta) { // FIXME
|
|
// for( yf = yfMin; yf < yfMax; yf = yf + yfDelta) { // FIXME
|
|
for( yf = yfMin; yf < yfMax; yf = yfDelta + yf ) { // FIXME
|
|
// printf("yf:%s min:%s max:%s\n", _ftostr(buf, yf), _ftostr(buf2, yfMin), _ftostr(buf3, yfMax));
|
|
#if 0
|
|
float yfD;
|
|
float a;
|
|
float b;
|
|
float yfSquare;
|
|
#endif
|
|
|
|
#if 0
|
|
/* add some very fake perspective */
|
|
yoff++;
|
|
xoff--;
|
|
#endif
|
|
// xfMax = sqrtf( yfMinSquare - yf * yf);
|
|
xfMax = sqrtf( yfMinSquare - (yf * yf));
|
|
xfMin = -xfMax; // trigger fnegeax
|
|
xfDelta = 1.0f;
|
|
|
|
// Constant terms from the inner loop
|
|
yfD = yf / yfDelta;
|
|
a = XResHalf + yfD;
|
|
// b= YMax + yfD - 90;
|
|
b= YMax + yfD - 90.0f;
|
|
|
|
yfSquare = yf * yf;
|
|
|
|
// for( xf = xfMin; xf < xfMax; xf += xfDelta) {
|
|
for( xf = xfMin; xf < xfMax; xf = xf + xfDelta) {
|
|
// printf("xf:%s xfmax:%s\n", _ftostr(buf2, xf), _ftostr(buf3, xfMax));
|
|
|
|
radiusf = .0327f * sqrtf( (xf * xf) + yfSquare);
|
|
|
|
zf = zScale * (cosf(7.7f * radiusf) +
|
|
cosf(8.5f * radiusf) +
|
|
cosf(9.3f * radiusf));
|
|
|
|
|
|
/* Scale to screen coordinates */
|
|
x = 1.0f * ( xf + a);
|
|
x += xoff;
|
|
|
|
y = 0.8f * ( b - zf);
|
|
y += yoff;
|
|
//printf("x: %d y: %d\n", x, y);
|
|
if( y > 0 && y < YRes) {
|
|
|
|
tgi_setpixel( x, y);
|
|
|
|
/* Clear horizon under y. */
|
|
if( y < YMax) {
|
|
tgi_setcolor (COLOR_BACK);
|
|
tgi_line( x, y + 1, x, YMax);
|
|
tgi_setcolor (COLOR_FORE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
cgetc();
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
|
|
5 dim xp, yp, r, fl, xr, yr, x, y, f
|
|
6 dim ad, yq, xl, q
|
|
7 m7 = 504
|
|
e4 = 40
|
|
8 yl = 200
|
|
n1 = -1
|
|
n5 = 0.5
|
|
nh = 900
|
|
eh = 100
|
|
hs = 160
|
|
sf = 3136
|
|
vz = 196
|
|
s = 1
|
|
a = 7872
|
|
10 dim bi(7), mi(319), ma(319), l(3000), p(30,120)
|
|
|
|
11 for t = 0 to 7
|
|
bi(7-t) = s
|
|
s = s + s
|
|
next : rem bit table
|
|
13 for t = 0 to yl
|
|
if (7 and t) = 0 then a = a + 320
|
|
14 l(t) = a
|
|
next : rem line addr table
|
|
15 for x = 0 to 319
|
|
mi(x) = yl
|
|
ma(x) = n1
|
|
next : rem min/max buffer
|
|
|
|
19 for y = 30 to 0 step n1
|
|
yq = y * y
|
|
xp = int(4 * sqr(nh - yq) + n5)
|
|
20 for x= 0 to xp
|
|
r = sqr(x * x / sf + yq /vz)
|
|
21 f = cos(r) - cos(3 * r) / 3 + cos(5 * r) / 5 - cos(7 * r) / 7
|
|
p(y, x) = int(e4 * f + n5)
|
|
22 fl = 0
|
|
xp = hs + x - y
|
|
yp = eh + y + y - p(y, x)
|
|
23 if mi(xp) > yp then mi(xp) = yp: fl = 1
|
|
24 if ma(xp) < yp then ma(xp) = yp: fl = 1
|
|
25 if fl = 0 or yp < z or yp >= yl then 27
|
|
26 ad = l(yp) + (xp and m7) + (yp and 7)
|
|
poke ad, peek(ad) or bi(xp and 7)
|
|
27 fl = 0
|
|
xp = hs - x - y
|
|
28 if mi(xp) > yp then mi(xp) = yp: fl = 1
|
|
29 if ma(xp) < yp then ma(xp) = yp: fl = 1
|
|
30 if fl = 0 or yp < z or yp >= yl then 32
|
|
31 ad = l(yp) + (xp and m7) + (yp and 7)
|
|
poke ad, peek(ad) or bi(xp and 7)
|
|
32 next
|
|
next
|
|
|
|
33 for y = -1 to -30 step n1
|
|
yq = y * y
|
|
xp = int(4 * sqr(nh - yq) + n5)
|
|
35 for x = 0 to xp
|
|
36 fl = 0
|
|
xp = hs + x - y
|
|
yp = eh + y + y - p(-y,x)
|
|
37 if mi(xp) > yp then mi(xp) = yp: fl = 1
|
|
38 if ma(xp) < yp then ma(xp) = yp: fl = 1
|
|
39 if fl = 0 or yp < z or yp >= yl then 41
|
|
40 ad = l(yp) + (xp and m7) + (yp and 7)
|
|
poke ad, peek(ad) or bi(xp and 7)
|
|
41 fl = 0
|
|
xp = hs - x - y
|
|
42 if mi(xp) > yp then mi(xp) = yp: fl = 1
|
|
43 if ma(xp) < yp then ma(xp) = yp: fl = 1
|
|
44 if fl = 0 or yp < z or yp >= yl then 46
|
|
45 ad = l(yp) + (xp and m7) + (yp and 7)
|
|
poke ad, peek(ad) or bi(xp and 7)
|
|
46 next
|
|
next
|
|
*/
|
|
|
|
int mi[320];
|
|
int ma[320];
|
|
|
|
int x, y;
|
|
int xp, yp;
|
|
int yq;
|
|
float r;
|
|
float f;
|
|
int p[30][120];
|
|
unsigned char fl;
|
|
|
|
void DoHat(void) {
|
|
|
|
tgi_setpalette (Palette);
|
|
tgi_setcolor (COLOR_FORE);
|
|
tgi_clear ();
|
|
|
|
for (x = 0; x < 320; x++) {
|
|
mi[x] = 200;
|
|
ma[x] = -1;
|
|
}
|
|
|
|
for (y = 30; y >= 0; y--) {
|
|
yq = y * y;
|
|
// xp = (int) (4.0f * sqrtf(900.0f - yq) + 0.5f); // Error: Invalid operands for binary operator '-'
|
|
xp = (int) (4.0f * sqrtf((float)(900 - yq)) + 0.5f);
|
|
|
|
for (x = 0; x < xp; x++) {
|
|
r = sqrtf((float)x * (float)x / 3136.0f + (float)yq / 196.0f);
|
|
f = cosf(r) - cosf(3.0f * r) / 3.0f + cosf(5.0f * r) / 5.0f - cosf(7.0f * r) / 7.0f;
|
|
p[y][x] = (int)((40.0f * f) + 0.5f);
|
|
fl = 0;
|
|
xp = 160 + x - y;
|
|
yp = 100 + y + y - p[y][x];
|
|
if (mi[xp] > yp) { mi[xp] = yp; fl = 1; }
|
|
if (ma[xp] < yp) { ma[xp] = yp; fl = 1; }
|
|
if (!((fl == 0) || (yp < 0) || (yp >= 200))) {
|
|
tgi_setpixel( xp, yp);
|
|
}
|
|
fl = 0;
|
|
xp = 160 - x - y;
|
|
|
|
if (mi[xp] > yp) { mi[xp] = yp; fl = 1; }
|
|
if (ma[xp] < yp) { ma[xp] = yp; fl = 1; }
|
|
if (!((fl == 0) || (yp < 0) || (yp >= 200))) {
|
|
tgi_setpixel( xp, yp);
|
|
}
|
|
}
|
|
}
|
|
cgetc();
|
|
}
|
|
|
|
int main (void)
|
|
{
|
|
unsigned char Border;
|
|
|
|
#if 1
|
|
|
|
#if DYN_DRV
|
|
/* Warn the user that the tgi driver is needed */
|
|
DoWarning ();
|
|
|
|
/* Load and initialize the driver */
|
|
tgi_load_driver (tgi_stddrv);
|
|
CheckError ("tgi_load_driver");
|
|
#else
|
|
/* Install the driver */
|
|
tgi_install (tgi_static_stddrv);
|
|
CheckError ("tgi_install");
|
|
#endif
|
|
|
|
tgi_init ();
|
|
CheckError ("tgi_init");
|
|
|
|
/* Get stuff from the driver */
|
|
MaxX = tgi_getmaxx ();
|
|
MaxY = tgi_getmaxy ();
|
|
AspectRatio = tgi_getaspectratio ();
|
|
|
|
/* Set the palette, set the border color */
|
|
Border = bordercolor (COLOR_BLACK);
|
|
#endif
|
|
/* Do graphics stuff */
|
|
Dosincos();
|
|
// DoHat();
|
|
|
|
#if DYN_DRV
|
|
/* Unload the driver */
|
|
tgi_unload ();
|
|
#else
|
|
/* Uninstall the driver */
|
|
tgi_uninstall ();
|
|
#endif
|
|
|
|
/* Reset the border */
|
|
(void) bordercolor (Border);
|
|
|
|
/* Done */
|
|
printf ("Done\n");
|
|
return EXIT_SUCCESS;
|
|
}
|