initial commit
This commit is contained in:
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
../../bin/oscar64 mbtext.c -n
|
||||
../../bin/oscar64 mbhires.c -n
|
||||
../../bin/oscar64 mbmulti.c -n
|
||||
../../bin/oscar64 mbmulti3d.c -n
|
||||
../../bin/oscar64 mbfixed.c -n -O3
|
||||
../../bin/oscar64 mbzoom.c -n -O3
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
call ..\..\bin\oscar64 mbtext.c -n
|
||||
call ..\..\bin\oscar64 mbhires.c -n
|
||||
call ..\..\bin\oscar64 mbmulti.c -n
|
||||
call ..\..\bin\oscar64 mbmulti3d.c -n
|
||||
call ..\..\bin\oscar64 mbfixed.c -n -O3
|
||||
call ..\..\bin\oscar64 mbzoom.c -n -O3
|
||||
@@ -0,0 +1,14 @@
|
||||
%.prg: %.c
|
||||
@echo "Compiling sample file" $<
|
||||
@$(OSCAR64_CC) $(OSCAR64_CFLAGS) $<
|
||||
|
||||
all: mbtext.prg mbtext.prg mbhires.prg mbmulti.prg mbmulti3d.prg mbfixed.prg mbzoom.prg
|
||||
|
||||
mbfixed.prg: mbfixed.c
|
||||
@$(OSCAR64_CC) $(OSCAR64_CFLAGS) -O3 $<
|
||||
|
||||
mbzoom.prg: mbzoom.c
|
||||
@$(OSCAR64_CC) $(OSCAR64_CFLAGS) -O3 $<
|
||||
|
||||
clean:
|
||||
@$(RM) *.asm *.int *.lbl *.map *.prg
|
||||
@@ -0,0 +1,100 @@
|
||||
#include <string.h>
|
||||
#include <c64/vic.h>
|
||||
#include <c64/memmap.h>
|
||||
#include <conio.h>
|
||||
#include <fixmath.h>
|
||||
|
||||
// Address of hires buffer and color buffers
|
||||
#define Screen ((char *)0xe000)
|
||||
#define Color ((char *)0xc800)
|
||||
#define Color2 ((char *)0xd800)
|
||||
|
||||
// Bit patterns for eight different color pairs
|
||||
char colors[] = {
|
||||
0xff, 0xff,
|
||||
0xee, 0xbb,
|
||||
0xaa, 0xaa,
|
||||
0x88, 0x22,
|
||||
|
||||
0x44, 0x11,
|
||||
0x55, 0x55,
|
||||
0xdd, 0x77,
|
||||
0x33, 0xcc
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Turn of the kernal ROM
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Switch VIC into multicolor bitmap mode
|
||||
vic_setmode(VICM_HIRES_MC, Color, Screen);
|
||||
|
||||
// Clear the screen and set the colors
|
||||
vic.color_back = 0x00;
|
||||
|
||||
memset(Screen, 0, 8000);
|
||||
memset(Color, 0x27, 1000);
|
||||
memset(Color2, 0x03, 1000);
|
||||
|
||||
// Loop over all pixels
|
||||
int py, px;
|
||||
|
||||
for(py=0; py<100; py++)
|
||||
{
|
||||
for(px=0; px<160; px++)
|
||||
{
|
||||
// Value in the complex plane
|
||||
|
||||
// int xz = (int)(((float)px * (3.5 / 160.0) - 2.5) * 4096 + 0.5);
|
||||
// int yz = (int)(((float)py * (2.4 / 100.0) - 1.2) * 4096 + 0.5);
|
||||
|
||||
int xz = lmul8f8s(px, (int)((3.5 / 160.0) * 4096 * 256)) - (int)(2.5 * 4096);
|
||||
int yz = lmul8f8s(py, (int)((2.4 / 100.0) * 4096 * 256)) - (int)(1.2 * 4096);
|
||||
|
||||
// Iterate up to 32 times
|
||||
int x = 0, y = 0;
|
||||
int i;
|
||||
for(i=0; i<32; i++)
|
||||
{
|
||||
unsigned long xq = lsqr4f12s(x), yq = lsqr4f12s(y);
|
||||
|
||||
if (xq + yq >= 0x04000000UL) break;
|
||||
|
||||
int xt = (int)(xq >> 12) - (int)(yq >> 12) + xz;
|
||||
y = 2 * lmul4f12s(x, y) + yz;
|
||||
x = xt;
|
||||
}
|
||||
|
||||
if (i < 32)
|
||||
{
|
||||
// Position on screen
|
||||
char * dp = Screen + 320 * (py >> 2) + 2 * (py & 3) + 2 * (px & ~3);
|
||||
|
||||
// Mask of pixels to change
|
||||
char mask = 0xc0 >> (2 * (px & 3));
|
||||
|
||||
// Get the two color patterns for upper and lower half
|
||||
char c0 = colors[2 * (i & 7)], c1 = colors[2 * (i & 7) + 1];
|
||||
|
||||
// Put the pixels into the image
|
||||
dp[0] |= c0 & mask;
|
||||
dp[1] |= c1 & mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable the kernal
|
||||
mmap_set(MMAP_NO_BASIC);
|
||||
|
||||
// Wait for key press
|
||||
getch();
|
||||
|
||||
// Restore VIC state
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#include <string.h>
|
||||
#include <c64/vic.h>
|
||||
#include <c64/memmap.h>
|
||||
#include <conio.h>
|
||||
|
||||
// Address of hires buffer and color buffer
|
||||
#define Screen ((char *)0xe000)
|
||||
#define Color ((char *)0xc800)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Turn of the kernal ROM
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Switch VIC into hires mode
|
||||
vic_setmode(VICM_HIRES, Color, Screen);
|
||||
|
||||
// Clear the screen
|
||||
memset(Screen, 0, 8000);
|
||||
memset(Color, 0x10, 1000);
|
||||
|
||||
// Loop over all pixels
|
||||
int py, px;
|
||||
|
||||
for(py=0; py<200; py++)
|
||||
{
|
||||
for(px=0; px<320; px++)
|
||||
{
|
||||
// Value in the complex plane
|
||||
|
||||
float xz = (float)px * (3.5 / 320.0)- 2.5;
|
||||
float yz = (float)py * (2.0 / 200.0) - 1.0;
|
||||
|
||||
// Iterate up to 32 times
|
||||
float x = 0.0, y = 0.0;
|
||||
int i;
|
||||
for(i=0; i<32; i++)
|
||||
{
|
||||
if (x * x + y * y > 4.0) break;
|
||||
|
||||
float xt = x * x - y * y + xz;
|
||||
y = 2 * x * y + yz;
|
||||
x = xt;
|
||||
}
|
||||
|
||||
// Set a pixel if exceeds bound in less than 32 iterations
|
||||
if (i < 32)
|
||||
Screen[320 * (py >> 3) + (py & 7) + (px & ~7)] |= 0x80 >> (px & 7);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable the kernal
|
||||
mmap_set(MMAP_NO_BASIC);
|
||||
|
||||
// Wait for key press
|
||||
getch();
|
||||
|
||||
// Restore VIC state
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
#include <string.h>
|
||||
#include <c64/vic.h>
|
||||
#include <c64/memmap.h>
|
||||
#include <conio.h>
|
||||
|
||||
// Address of hires buffer and color buffers
|
||||
#define Screen ((char *)0xe000)
|
||||
#define Color ((char *)0xc800)
|
||||
#define Color2 ((char *)0xd800)
|
||||
|
||||
// Bit patterns for eight different color pairs
|
||||
char colors[] = {
|
||||
0xff, 0xff,
|
||||
0xee, 0xbb,
|
||||
0xaa, 0xaa,
|
||||
0x88, 0x22,
|
||||
|
||||
0x44, 0x11,
|
||||
0x55, 0x55,
|
||||
0xdd, 0x77,
|
||||
0x33, 0xcc
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Turn of the kernal ROM
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Switch VIC into multicolor bitmap mode
|
||||
vic_setmode(VICM_HIRES_MC, Color, Screen);
|
||||
|
||||
// Clear the screen and set the colors
|
||||
vic.color_back = 0x00;
|
||||
|
||||
memset(Screen, 0, 8000);
|
||||
memset(Color, 0x27, 1000);
|
||||
memset(Color2, 0x03, 1000);
|
||||
|
||||
// Loop over all pixels
|
||||
int py, px;
|
||||
|
||||
for(py=0; py<100; py++)
|
||||
{
|
||||
for(px=0; px<160; px++)
|
||||
{
|
||||
// Value in the complex plane
|
||||
|
||||
float xz = (float)px * (3.5 / 160.0)- 2.5;
|
||||
float yz = (float)py * (2.4 / 100.0) - 1.2;
|
||||
|
||||
// Iterate up to 32 times
|
||||
float x = 0.0, y = 0.0;
|
||||
int i;
|
||||
for(i=0; i<32; i++)
|
||||
{
|
||||
if (x * x + y * y > 4.0) break;
|
||||
|
||||
float xt = x * x - y * y + xz;
|
||||
y = 2 * x * y + yz;
|
||||
x = xt;
|
||||
}
|
||||
|
||||
if (i < 32)
|
||||
{
|
||||
// Position on screen
|
||||
char * dp = Screen + 320 * (py >> 2) + 2 * (py & 3) + 2 * (px & ~3);
|
||||
|
||||
// Mask of pixels to change
|
||||
char mask = 0xc0 >> (2 * (px & 3));
|
||||
|
||||
// Get the two color patterns for upper and lower half
|
||||
char c0 = colors[2 * (i & 7)], c1 = colors[2 * (i & 7) + 1];
|
||||
|
||||
// Put the pixels into the image
|
||||
dp[0] |= c0 & mask;
|
||||
dp[1] |= c1 & mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable the kernal
|
||||
mmap_set(MMAP_NO_BASIC);
|
||||
|
||||
// Wait for key press
|
||||
getch();
|
||||
|
||||
// Restore VIC state
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
#include <string.h>
|
||||
#include <c64/vic.h>
|
||||
#include <c64/memmap.h>
|
||||
#include <conio.h>
|
||||
#include <math.h>
|
||||
|
||||
// Address of hires buffer and color buffers
|
||||
#define Screen ((char *)0xe000)
|
||||
#define Color1 ((char *)0xc800)
|
||||
#define Color2 ((char *)0xd800)
|
||||
|
||||
// Bit patterns for two different color pairs and eight shades
|
||||
byte colors[2][17] =
|
||||
{
|
||||
{0x00,
|
||||
0x44, 0x44, 0x55, 0x55, 0xdd, 0xdd, 0xff, 0xff,
|
||||
0x88, 0x88, 0xaa, 0xaa, 0xee, 0xee, 0xff, 0xff,
|
||||
},
|
||||
{0x00,
|
||||
0x00, 0x11, 0x11, 0x55, 0x55, 0x77, 0x77, 0xff,
|
||||
0x00, 0x22, 0x22, 0xaa, 0xaa, 0xbb, 0xbb, 0xff,
|
||||
}
|
||||
};
|
||||
|
||||
// Fill a vertical line x from py to ty with color c
|
||||
void VLine(int x, int py, int ty, char c)
|
||||
{
|
||||
// Clip boundaries
|
||||
if (py < 0)
|
||||
py = 0;
|
||||
if (ty > 100)
|
||||
ty = 100;
|
||||
|
||||
// Check if there are pixel to draw
|
||||
if (py < ty)
|
||||
{
|
||||
// Calculate top address and mask
|
||||
char mask = 0xc0 >> (2 * (x & 3));
|
||||
char * dp = Screen + 320 * (py >> 2) + 2 * (py & 3) + 2 * (x & ~3);
|
||||
|
||||
// Get the two color patterns
|
||||
char c0 = colors[0][c] & mask, c1 = colors[1][c] & mask;
|
||||
|
||||
// Invert mask to cover the unchanged portion
|
||||
mask = ~mask;
|
||||
|
||||
// Loop over all pixels
|
||||
char h = ty - py;
|
||||
while (h)
|
||||
{
|
||||
// Apply color to memory
|
||||
dp[0] = (dp[0] & mask) | c0;
|
||||
dp[1] = (dp[1] & mask) | c1;
|
||||
|
||||
// Two pixel lines down
|
||||
dp += 2;
|
||||
if (!((int)dp & 7))
|
||||
dp += 312;
|
||||
|
||||
h--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate up to 32 iterations and return a smoothed height
|
||||
float iter(float xz, float yz)
|
||||
{
|
||||
float x = 0.0, y = 0.0, r;
|
||||
int i;
|
||||
for(i=0; i<32; i++)
|
||||
{
|
||||
r = x * x + y * y;
|
||||
if (r > 64.0) break;
|
||||
|
||||
float xt = x * x - y * y + xz;
|
||||
y = 2 * x * y + yz;
|
||||
x = xt;
|
||||
}
|
||||
|
||||
|
||||
if (i == 32)
|
||||
return 32;
|
||||
else
|
||||
return i - log(log(r)/log(64.0))/log(2.0);
|
||||
}
|
||||
|
||||
// Calculate light with given new and old heights
|
||||
int light(float hl, float hu, float h)
|
||||
{
|
||||
float dx = h - hl, dz = h - hu, dy = 0.1;
|
||||
|
||||
float dd = sqrt(dx * dx + dy * dy + dz * dz);
|
||||
int ni = (int)floor((-2 * dx + dy + dz) / dd * 0.408 * 8);
|
||||
if (ni < 0) ni = 0; else if (ni > 7) ni = 7;
|
||||
|
||||
return ni;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Turn of the kernal ROM
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Switch VIC into multicolor bitmap mode
|
||||
vic_setmode(VICM_HIRES_MC, Color1, Screen);
|
||||
|
||||
// Clear the screen and set the colors
|
||||
vic.color_back = 0x00;
|
||||
vic.color_border = 0x00;
|
||||
|
||||
memset(Screen, 0, 8000);
|
||||
memset(Color1, 0x26, 1000);
|
||||
memset(Color2, 0x0f, 1000);
|
||||
|
||||
// Height of previous row, needed for lighting
|
||||
float hl[200];
|
||||
|
||||
// Rotation of complex plane
|
||||
float w = -0.7;
|
||||
float co = cos(w), si = sin(w);
|
||||
|
||||
// Loop from left to right
|
||||
for(int x=-1; x<160; x+= 1)
|
||||
{
|
||||
// Loop from far to nead
|
||||
int py = 20;
|
||||
float hu = 0;
|
||||
for(int y=1; y<200; y+= 1)
|
||||
{
|
||||
// Inverse 3D projection
|
||||
float fz = 2.0 / (float)y;
|
||||
float fx = (float)(x - 80) * fz / 100.0;
|
||||
|
||||
float mz = fz * 100.0 - 3.0, mx = fx * 100.0;
|
||||
|
||||
// Rotation of the plane
|
||||
float rx = mx * co - mz * si, rz = mx * si + mz * co;
|
||||
float dp = iter(rx, rz);
|
||||
float v = 2 * dp;
|
||||
if (v < 1.0) v = 1.0;
|
||||
|
||||
float fy = 5.0 * pow(2.0, - v * 0.4);
|
||||
|
||||
// Calculate light
|
||||
int ni = light(hl[y], hu, fy);
|
||||
|
||||
// Update left column
|
||||
hl[y] = fy;
|
||||
hu = fy;
|
||||
|
||||
// Forward 3D projection
|
||||
int ty = 20 + y / 2 + (int)(floor(fy / fz));
|
||||
|
||||
|
||||
// color of pixel
|
||||
int c;
|
||||
if (dp != 32)
|
||||
c = 1 + ni + 8 * ((int)floor(dp) & 1);
|
||||
else
|
||||
c = 0;
|
||||
|
||||
// Draw line if not dummy left row
|
||||
if (x >= 0)
|
||||
VLine(x, py, ty, c);
|
||||
|
||||
py = ty;
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable the kernal
|
||||
mmap_set(MMAP_NO_BASIC);
|
||||
|
||||
// Wait for key press
|
||||
getch();
|
||||
|
||||
// Restore VIC state
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,36 @@
|
||||
#include <string.h>
|
||||
|
||||
#define Screen ((char *)0x0400)
|
||||
#define Color ((char *)0xd800)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
memset(Screen, 160, 1024);
|
||||
|
||||
int py, px;
|
||||
|
||||
for(py=0; py<25; py++)
|
||||
{
|
||||
for(px=0; px<40; px++)
|
||||
{
|
||||
float xz = (float)px * (3.5 / 40.0)- 2.5;
|
||||
float yz = (float)py * (2.0 / 25.0) - 1.0;
|
||||
|
||||
float x = 0.0, y = 0.0;
|
||||
int i;
|
||||
for(i=0; i<=14; i++)
|
||||
{
|
||||
if (x * x + y * y > 4.0) break;
|
||||
|
||||
float xt = x * x - y * y + xz;
|
||||
y = 2 * x * y + yz;
|
||||
x = xt;
|
||||
}
|
||||
i--;
|
||||
|
||||
Color[py * 40 + px] = i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
#include <c64/vic.h>
|
||||
|
||||
#define Screen ((char *)0x0400)
|
||||
#define Color ((char *)0xd800)
|
||||
|
||||
// Lookup table for squares from 0..255
|
||||
__striped unsigned sqb[256];
|
||||
|
||||
// Shift byte right and left by 4
|
||||
char shlb4[256], shrb4[256];
|
||||
|
||||
#pragma align(sqb, 256);
|
||||
|
||||
// Square an unsigned int into an unsigned long
|
||||
inline unsigned long ssquare(unsigned x)
|
||||
{
|
||||
// Split into low byte and highbyte, so we have x = a + 0x100 * b
|
||||
|
||||
unsigned a = x & 0xff;
|
||||
unsigned b = x >> 8;
|
||||
|
||||
// So now we calculate (a + 0x100 * b)²
|
||||
// Result will be a² + 0x100 * 2 * a * b + 0x10000 * b²
|
||||
// with 2 * a * b == (a + b)² - a² - b²
|
||||
|
||||
// We can cover all cases with the square table except if a + b >= 0x100
|
||||
// in this case we have abp := a + b - 0x100
|
||||
// (abp + 0x100)² == abp² + 2 * 0x100 * abp + 0x10000
|
||||
|
||||
// Get squares of the bytes and the sum of the bytes
|
||||
unsigned a2 = sqb[a], b2 = sqb[b];
|
||||
unsigned apb = a + b;
|
||||
|
||||
// First approximation approximation
|
||||
// a² + 0x10000 * b²
|
||||
unsigned long sum = a2 + ((unsigned long)b2 << 16);
|
||||
|
||||
// Check if a + b >= 0x100
|
||||
if (apb & 0xff00)
|
||||
{
|
||||
apb &= 0xff;
|
||||
sum += 0x1000000UL;
|
||||
sum += (unsigned long)apb << 17;
|
||||
sum += (unsigned long)sqb[apb] << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
apb &= 0xff;
|
||||
sum += (unsigned long)sqb[apb] << 8;
|
||||
}
|
||||
|
||||
// Now w have a² + 0x1000 * b² + (a + b)²
|
||||
|
||||
sum -= (unsigned long)a2 << 8;
|
||||
sum -= (unsigned long)b2 << 8;
|
||||
|
||||
// And finally the complete result
|
||||
return sum;
|
||||
}
|
||||
|
||||
// Signed square of x
|
||||
inline long sq(int x)
|
||||
{
|
||||
if (x < 0)
|
||||
x = -x;
|
||||
return ssquare(x);
|
||||
}
|
||||
|
||||
// Colors to fill in the different levels
|
||||
static const char colors[32] = {
|
||||
VCOL_BLUE,
|
||||
VCOL_LT_BLUE,
|
||||
VCOL_WHITE,
|
||||
VCOL_LT_GREEN,
|
||||
VCOL_GREEN,
|
||||
VCOL_YELLOW,
|
||||
VCOL_ORANGE,
|
||||
VCOL_RED,
|
||||
VCOL_PURPLE,
|
||||
|
||||
VCOL_BLUE,
|
||||
VCOL_BLUE,
|
||||
VCOL_LT_BLUE,
|
||||
VCOL_LT_BLUE,
|
||||
VCOL_WHITE,
|
||||
VCOL_WHITE,
|
||||
VCOL_LT_GREEN,
|
||||
VCOL_LT_GREEN,
|
||||
VCOL_GREEN,
|
||||
VCOL_GREEN,
|
||||
VCOL_YELLOW,
|
||||
VCOL_YELLOW,
|
||||
VCOL_ORANGE,
|
||||
VCOL_ORANGE,
|
||||
VCOL_RED,
|
||||
VCOL_RED,
|
||||
VCOL_PURPLE,
|
||||
VCOL_PURPLE,
|
||||
|
||||
VCOL_LT_GREY,
|
||||
VCOL_LT_GREY,
|
||||
VCOL_MED_GREY,
|
||||
VCOL_MED_GREY,
|
||||
VCOL_DARK_GREY,
|
||||
};
|
||||
|
||||
inline int shr12(long l)
|
||||
{
|
||||
char b3 = (l >> 24) & 0xff;
|
||||
char b2 = (l >> 16) & 0xff;
|
||||
char b1 = (l >> 8) & 0xff;
|
||||
char a0 = shrb4[b1] | shlb4[b2];
|
||||
char a1 = shrb4[b2] | shlb4[b3];
|
||||
return a0 | (a1 << 8);
|
||||
}
|
||||
|
||||
// Return color for a given coordinate in the complex plane using
|
||||
// 12.4bit fixed numbers using m'=m²+b
|
||||
|
||||
inline char fcolor(int xz, int yz)
|
||||
{
|
||||
// Start value for iteration is the offset value itself
|
||||
|
||||
int x = xz, y = yz;
|
||||
|
||||
// Iterate up to 32 steps
|
||||
|
||||
for(int i=0; i<32; i++)
|
||||
{
|
||||
// Build squares of real and imaginary component
|
||||
long xx = sq(x), yy = sq(y), xxyy = sq(x + y);
|
||||
|
||||
long xxpyy = xx + yy;
|
||||
|
||||
// Use squares to check for exit condition of sure
|
||||
// to progress towards infinity
|
||||
if (xxpyy >= 4L * 4096 * 4096) return colors[i];
|
||||
|
||||
// Next iteration values using complex arithmetic
|
||||
// Mx' = Mx² - My² + Bx
|
||||
// My' = 2 * Mx * My + By = (Mx + My)² - Mx² - My² + By
|
||||
x = shr12(xx - yy + 2048) + xz;
|
||||
y = shr12(xxyy - xxpyy + 2048) + yz;
|
||||
}
|
||||
|
||||
// More than maximum number of iterations, so assume progress
|
||||
// towards zero
|
||||
|
||||
return VCOL_BLACK;
|
||||
}
|
||||
|
||||
// Fill a row with color
|
||||
void fill_row(char py, int cix, int yz, int cis)
|
||||
{
|
||||
int xz = cix;
|
||||
for(int px=0; px<40; px++)
|
||||
{
|
||||
Color[py * 40 + px] = fcolor(xz, yz);
|
||||
xz += cis;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill a column with color
|
||||
void fill_column(char px, int xz, int ciy, int cis)
|
||||
{
|
||||
int yz = ciy;
|
||||
for(int py=0; py<25; py++)
|
||||
{
|
||||
Color[py * 40 + px] = fcolor(xz, yz);
|
||||
yz += cis;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the complete image
|
||||
void fill_image(int cix, int ciy, int cis)
|
||||
{
|
||||
int yz = ciy;
|
||||
for(int py=0; py<25; py++)
|
||||
{
|
||||
fill_row(py, cix, yz, cis);
|
||||
yz += cis;
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll screen to the left
|
||||
void scroll_left(void)
|
||||
{
|
||||
for(char x=0; x<39; x++)
|
||||
{
|
||||
#pragma unroll(full)
|
||||
for(char y=0; y<25; y++)
|
||||
{
|
||||
Color[y * 40 + x] = Color[y * 40 + x + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll screen to the right
|
||||
void scroll_right(void)
|
||||
{
|
||||
for(signed char x=38; x>=0; x--)
|
||||
{
|
||||
#pragma unroll(full)
|
||||
for(char y=0; y<25; y++)
|
||||
{
|
||||
Color[y * 40 + x + 1] = Color[y * 40 + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll screen up
|
||||
void scroll_up(void)
|
||||
{
|
||||
for(char x=0; x<40; x++)
|
||||
{
|
||||
#pragma unroll(full)
|
||||
for(char y=0; y<24; y++)
|
||||
{
|
||||
Color[y * 40 + x] = Color[(y + 1) * 40 + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll screen down
|
||||
void scroll_down(void)
|
||||
{
|
||||
for(char x=0; x<40; x++)
|
||||
{
|
||||
#pragma unroll(full)
|
||||
for(char y=0; y<24; y++)
|
||||
{
|
||||
Color[(24 - y) * 40 + x] = Color[(23 - y) * 40 + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Initialize square table
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
sqb[i] = i * i;
|
||||
shlb4[i] = i << 4;
|
||||
shrb4[i] = i >> 4;
|
||||
}
|
||||
|
||||
// Clear screen
|
||||
memset(Screen, 160, 1024);
|
||||
|
||||
// Start coordinates in float
|
||||
float cx = -0.4;
|
||||
float cy = 0.0;
|
||||
float cw = 3.2;
|
||||
|
||||
// Convert to top, left and step in 12.4 fixed point
|
||||
int cix = (int)((cx - 0.5 * cw) * 4096);
|
||||
int ciy = (int)((cy - 12.0 * cw / 40.0) * 4096);
|
||||
int cis = (int)(cw / 40.0 * 4096);
|
||||
|
||||
// Initial image
|
||||
fill_image(cix, ciy, cis);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// Wait for keypress
|
||||
char ch = getch();
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case 'S':
|
||||
ciy += cis;
|
||||
scroll_up();
|
||||
fill_row(24, cix, ciy + 24 * cis, cis);
|
||||
break;
|
||||
case 'W':
|
||||
ciy -= cis;
|
||||
scroll_down();
|
||||
fill_row(0, cix, ciy, cis);
|
||||
break;
|
||||
case 'A':
|
||||
cix -= cis;
|
||||
scroll_right();
|
||||
fill_column(0, cix, ciy, cis);
|
||||
break;
|
||||
case 'D':
|
||||
cix += cis;
|
||||
scroll_left();
|
||||
fill_column(39, cix + 39 * cis, ciy, cis);
|
||||
break;
|
||||
case '+':
|
||||
cix += 20 * cis;
|
||||
ciy += 12 * cis;
|
||||
cis = cis * 2 / 3;
|
||||
cix -= 20 * cis;
|
||||
ciy -= 12 * cis;
|
||||
fill_image(cix, ciy, cis);
|
||||
break;
|
||||
case '-':
|
||||
cix += 20 * cis;
|
||||
ciy += 12 * cis;
|
||||
cis = cis * 3 / 2;
|
||||
cix -= 20 * cis;
|
||||
ciy -= 12 * cis;
|
||||
fill_image(cix, ciy, cis);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user