2012-02-14 05:46:00 +04:00
|
|
|
/*
|
|
|
|
* Julia Fractal Generator
|
2012-07-07 08:08:28 +04:00
|
|
|
*
|
|
|
|
* This is the updated windowed version of the
|
|
|
|
* julia fractal generator demo.
|
2012-02-14 05:46:00 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <syscall.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <unistd.h>
|
2012-03-15 00:04:12 +04:00
|
|
|
#include <getopt.h>
|
2012-02-14 05:46:00 +04:00
|
|
|
|
|
|
|
#include "lib/window.h"
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
#include "lib/graphics.h"
|
2012-03-15 00:04:12 +04:00
|
|
|
#include "lib/decorations.h"
|
2012-02-14 05:46:00 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Macros make verything easier.
|
|
|
|
*/
|
|
|
|
#define SPRITE(sprite,x,y) sprite->bitmap[sprite->width * (y) + (x)]
|
|
|
|
|
2012-03-15 00:04:12 +04:00
|
|
|
#define GFX_(xpt, ypt) ((uint32_t *)window->buffer)[DIRECT_OFFSET(xpt+decor_left_width,ypt+decor_top_height)]
|
2012-02-14 05:46:00 +04:00
|
|
|
|
|
|
|
/* Pointer to graphics memory */
|
|
|
|
window_t * window = NULL;
|
|
|
|
|
|
|
|
/* Julia fractals elements */
|
|
|
|
float conx = -0.74; /* real part of c */
|
|
|
|
float cony = 0.1; /* imag part of c */
|
|
|
|
float Maxx = 2; /* X bounds */
|
|
|
|
float Minx = -2;
|
|
|
|
float Maxy = 1; /* Y bounds */
|
|
|
|
float Miny = -1;
|
|
|
|
float initer = 1000; /* Iteration levels */
|
|
|
|
float pixcorx; /* Internal values */
|
|
|
|
float pixcory;
|
|
|
|
|
|
|
|
int newcolor; /* Color we're placing */
|
|
|
|
int lastcolor; /* Last color we placed */
|
|
|
|
int no_repeat = 0; /* Repeat colors? */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Color table
|
|
|
|
* These are orange/red shades from the Ubuntu platte.
|
|
|
|
*/
|
|
|
|
int colors[] = {
|
|
|
|
0xeec73e,
|
|
|
|
0xf0a513,
|
|
|
|
0xfb8b00,
|
|
|
|
0xf44800,
|
|
|
|
0xffff99,
|
|
|
|
0xffff00,
|
|
|
|
0xfdca01,
|
|
|
|
0x986601,
|
|
|
|
0xf44800,
|
|
|
|
0xfd3301,
|
|
|
|
0xd40000,
|
|
|
|
0x980101,
|
|
|
|
};
|
|
|
|
|
|
|
|
void julia(int xpt, int ypt) {
|
|
|
|
long double x = xpt * pixcorx + Minx;
|
|
|
|
long double y = Maxy - ypt * pixcory;
|
|
|
|
long double xnew = 0;
|
|
|
|
long double ynew = 0;
|
|
|
|
|
|
|
|
int k = 0;
|
|
|
|
for (k = 0; k <= initer; k++) {
|
|
|
|
xnew = x * x - y * y + conx;
|
|
|
|
ynew = 2 * x * y + cony;
|
|
|
|
x = xnew;
|
|
|
|
y = ynew;
|
|
|
|
if ((x * x + y * y) > 4)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
int color;
|
|
|
|
if (no_repeat) {
|
|
|
|
color = 12 * k / initer;
|
|
|
|
} else {
|
|
|
|
color = k;
|
|
|
|
if (color > 11) {
|
|
|
|
color = color % 12;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (k >= initer) {
|
2012-03-15 00:04:12 +04:00
|
|
|
GFX_(xpt,ypt) = 0;
|
2012-02-14 05:46:00 +04:00
|
|
|
} else {
|
2012-03-15 00:04:12 +04:00
|
|
|
GFX_(xpt,ypt) = colors[color];
|
2012-02-14 05:46:00 +04:00
|
|
|
}
|
|
|
|
newcolor = color;
|
|
|
|
}
|
|
|
|
|
2012-03-15 00:04:12 +04:00
|
|
|
void usage(char * argv[]) {
|
|
|
|
printf(
|
|
|
|
"Julia fractal generator.\n"
|
|
|
|
"\n"
|
|
|
|
"usage: %s [-n] [-i \033[3miniter\033[0m] [-x \033[3mminx\033[0m] \n"
|
|
|
|
" [-X \033[3mmaxx\033[0m] [-c \033[3mconx\033[0m] [-C \033[3mcony\033[0m]\n"
|
|
|
|
" [-W \033[3mwidth\033[0m] [-H \033[3mheight\033[0m] [-h]\n"
|
|
|
|
"\n"
|
|
|
|
" -n --no-repeat \033[3mDo not repeat colors\033[0m\n"
|
|
|
|
" -i --initer \033[3mInitializer value\033[0m\n"
|
|
|
|
" -x --minx \033[3mMinimum X value\033[0m\n"
|
|
|
|
" -X --maxx \033[3mMaximum X value\033[0m\n"
|
|
|
|
" -c --conx \033[3mcon x\033[0m\n"
|
|
|
|
" -C --cony \033[3mcon y\033[0m\n"
|
|
|
|
" -W --width \033[3mWindow width\033[0m\n"
|
|
|
|
" -H --height \033[3mWindow height\033[0m\n"
|
|
|
|
" -h --help \033[3mShow this help message.\033[0m\n",
|
|
|
|
argv[0]);
|
|
|
|
}
|
2012-02-14 05:46:00 +04:00
|
|
|
|
2012-03-15 00:04:12 +04:00
|
|
|
int main(int argc, char * argv[]) {
|
|
|
|
int left = 40;
|
|
|
|
int top = 40;
|
|
|
|
int width = 300;
|
|
|
|
int height = 300;
|
|
|
|
|
|
|
|
static struct option long_opts[] = {
|
|
|
|
{"no-repeat", no_argument, 0, 'n'},
|
|
|
|
{"initer", required_argument, 0, 'i'},
|
|
|
|
{"minx", required_argument, 0, 'x'},
|
|
|
|
{"maxx", required_argument, 0, 'X'},
|
|
|
|
{"conx", required_argument, 0, 'c'},
|
|
|
|
{"cony", required_argument, 0, 'C'},
|
|
|
|
{"width", required_argument, 0, 'W'},
|
|
|
|
{"height", required_argument, 0, 'H'},
|
|
|
|
{"help", no_argument, 0, 'h'},
|
|
|
|
{0,0,0,0}
|
|
|
|
};
|
2012-02-14 05:46:00 +04:00
|
|
|
|
|
|
|
if (argc > 1) {
|
|
|
|
/* Read some arguments */
|
|
|
|
int index, c;
|
2012-03-15 00:04:12 +04:00
|
|
|
while ((c = getopt_long(argc, argv, "ni:x:X:c:C:W:H:h", long_opts, &index)) != -1) {
|
|
|
|
if (!c) {
|
|
|
|
if (long_opts[index].flag == 0) {
|
|
|
|
c = long_opts[index].val;
|
|
|
|
}
|
|
|
|
}
|
2012-02-14 05:46:00 +04:00
|
|
|
switch (c) {
|
|
|
|
case 'n':
|
|
|
|
no_repeat = 1;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
initer = atof(optarg);
|
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
Minx = atof(optarg);
|
|
|
|
break;
|
|
|
|
case 'X':
|
|
|
|
Maxx = atof(optarg);
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
conx = atof(optarg);
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
cony = atof(optarg);
|
|
|
|
break;
|
2012-03-15 00:04:12 +04:00
|
|
|
case 'W':
|
|
|
|
width = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'H':
|
|
|
|
height = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
usage(argv);
|
|
|
|
exit(0);
|
|
|
|
break;
|
2012-02-14 05:46:00 +04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-03-15 00:04:12 +04:00
|
|
|
|
|
|
|
setup_windowing();
|
|
|
|
|
|
|
|
window = window_create(left, top, width + decor_width(), height + decor_height());
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
//window_fill(window, rgb(127,127,127));
|
2012-03-15 00:04:12 +04:00
|
|
|
init_decorations();
|
|
|
|
render_decorations(window, window->buffer, "Julia Fractals");
|
|
|
|
|
2012-02-14 05:46:00 +04:00
|
|
|
printf("initer: %f\n", initer);
|
|
|
|
printf("X: %f %f\n", Minx, Maxx);
|
|
|
|
float _x = Maxx - Minx;
|
|
|
|
float _y = _x / width * height;
|
|
|
|
Miny = 0 - _y / 2;
|
|
|
|
Maxy = _y / 2;
|
|
|
|
printf("Y: %f %f\n", Miny, Maxy);
|
|
|
|
printf("conx: %f cony: %f\n", conx, cony);
|
|
|
|
|
|
|
|
pixcorx = (Maxx - Minx) / width;
|
|
|
|
pixcory = (Maxy - Miny) / height;
|
|
|
|
int j = 0;
|
|
|
|
do {
|
|
|
|
int i = 1;
|
|
|
|
do {
|
|
|
|
julia(i,j);
|
|
|
|
if (lastcolor != newcolor) julia(i-1,j);
|
|
|
|
else if (i > 0) GFX_(i-1,j) = colors[lastcolor];
|
|
|
|
newcolor = lastcolor;
|
|
|
|
i+= 2;
|
|
|
|
} while ( i < width );
|
|
|
|
++j;
|
|
|
|
} while ( j < height );
|
|
|
|
|
2012-03-15 00:04:12 +04:00
|
|
|
int playing = 1;
|
|
|
|
while (playing) {
|
|
|
|
char ch = 0;
|
|
|
|
w_keyboard_t * kbd;
|
|
|
|
do {
|
|
|
|
kbd = poll_keyboard();
|
|
|
|
if (kbd != NULL) {
|
|
|
|
ch = kbd->key;
|
|
|
|
free(kbd);
|
|
|
|
}
|
|
|
|
} while (kbd != NULL);
|
|
|
|
|
|
|
|
switch (ch) {
|
|
|
|
case 'q':
|
|
|
|
playing = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
syscall_yield();
|
2012-02-14 05:46:00 +04:00
|
|
|
}
|
|
|
|
|
2012-03-15 00:04:12 +04:00
|
|
|
printf("Closing down Julia Fractal Generate\n");
|
|
|
|
|
|
|
|
teardown_windowing();
|
2012-03-24 02:44:37 +04:00
|
|
|
printf("Exiting...\n");
|
2012-03-15 00:04:12 +04:00
|
|
|
|
2012-02-14 05:46:00 +04:00
|
|
|
return 0;
|
|
|
|
}
|