/*
* copyright..: (C)2007 Sebastian Mach
* contact....: http://greenhybrid.net | [email protected]
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************\
What Monsieur Mach learned while trying to hack a 4k, Issue A
---------------------------------------------------------------
(C)2007 Sebastian Mach
http://greenhybrid.net | [email protected]
* use constants which have dedicated support in the fpu (e.g. 0.0,1.0)
can save 8 and more bytes per use
e.g.: - imagine a function g() with return value [-1..+1]
- you want to map it to [0..1]
- instead of g()*0.5+0.5, you should definitely use (g()+1.0)*
0.5
* if a lot of calls to the same function exist, and if their return-
val is not changed in code-structure, then it may be better to do
all the calls in a loop and save the results in an array (see e.g.
defRandomXForms(), where a lot of calls to a random number generator
have been pushed into a lookup-table generator)
* changing lengths of arrays can cause size-explosions of >1k. do this
carefully, both when increasing and decreasing. sizes of 2^n are
less harsmfull in most cases.
* SDL eats around 1k for simple screen buffer alloc and surface-
lockin g
* SDL eats around 0.1k for SDL_WM_SetCaption()
* test if loop unrolling is beneficial or not. a loop like
"for(u=0; u<3; u++ ) c[u] = 0;"
might be beneficial. a loop like
"for(u=0; u<3; u++ ) c[u] = pow(x,4)/sqrt(y) * 3.14159;"
not.
* step by step: a) compile and check size; b) tweak; c) a);
What Monsieur Mach learned while trying to hack a 4k, Issue B
---------------------------------------------------------------
(C)2007 Sebastian Mach
http://greenhybrid.net | [email protected]
* why declare functions static? does that lower the size of functions?
- no. but it says the compiler "heya, that function will definitely
only referenced to from within this file. if not referenced from
within this file, you can prune it and save space in the
binary".
* if you want to know the current state of key, you can use
SDL_PumpEvents and SDL_GetKeyState instead of a blown SDL_Poll-
Events-monstrum. that can save you several bytes (but might not, if
you need an event-polling anyway.
\****************************************************************************/
/****************************************************************************\
* include *
\****************************************************************************/
#include <SDL/SDL.h>
#include <dlfcn.h>
#include <math.h>
/****************************************************************************\
* definitions *
\****************************************************************************/
#define IDIOT( C ) if( C ){ DUMPTEXT( "IDIOT!", 6 ); }
//>program args
#define WIDTH (640)
#define HEIGHT (480)
//>ifs args
#define SAMPLES_PER_CALL 64
#define DISCARD_SAMPLE_NUM 32
#define MAX_SAMPLE_LENGTH 512
#define MAX_NUM_XFORMS 10 /* adjust this with care! for some reason the size might go +1400 bytes */
#define MAX_NUM_XFORMS_SQ (MAX_NUM_XFORMS*MAX_NUM_XFORMS)
//> below outcommented lines are for pure rotation, but see defRandomXForms
#define ROT_PROB 0.5
#define TRANS_AFTER_ROT_PROB 0.5
#define TRANS_AFTER_ROT_SCALE 0.5
#define ROT_SCALE 1.0
#define ROT_ADD 0.0
#define FLAME_RANDOM_COEFFICIENT (FTMP2=sfrand(),FTMP2*FTMP2*FTMP2) /*pow(sfrand(),9)*/
#define RANDOM_NUM_XFORMS ( urand() % 5 + 4 )
//>program config
//#define DEFINE_FUNCTION_noise
//#define DEFINE_FUNCTION_operate
#define LINUX
//>low level
#ifdef LINUX
#define DUMPTEXT( txt, len ) \
asm volatile ( "":::"%eax", "%ebx", "%ecx", "%edx" );\
asm volatile ( "int $0x80" \
: \
: "a"(4), "b"(1), "c"(txt), "d"(len) \
); \
asm volatile ( "":::"%eax", "%ebx", "%ecx", "%edx" );
#define BYEBYE() asm( "int $0x80" :: "a"(1), "b"(42) );
#endif
/****************************************************************************\
* here go the types *
\****************************************************************************/
typedef double scalar;
typedef union _t_pixel{
struct{
scalar r,g,b,density;
};
scalar m[4];
} t_pixel;
/*typedef enum _t_OP{
OP_ADD,
OP_SUB,
OP_MUL,
OP_DIV
} t_OP;*/
#define NUM_FLAME_COEFFICIENTS 17
typedef union _t_flameCoeff{
struct{
scalar linear;
scalar sinusoidal;
scalar spherical;
scalar swirl;
scalar horseshoe;
scalar polar;
scalar handkerchief;
scalar heart;
scalar disc;
scalar spiral;
scalar hyperbolic;
scalar diamond;
scalar ex;
scalar julia;
scalar fisheye;
scalar cosine;
scalar cust_hyperbolic;
};
scalar coeff[NUM_FLAME_COEFFICIENTS];
} t_flameCoeff;
typedef union _t_xform{
scalar m[9];
struct{
scalar x1, x2, x;
scalar y1, y2, y;
scalar r,g,b;
};
} t_xform;
/*
typedef struct _t_dsmState{
scalar registers[256];
scalar stack[256];
int stackPtr;
unsigned int codePtr;
} t_dsmState;
typedef union _t_dsmOpCode{
unsigned char opc : 8; // op code
unsigned char index : 8;
char relAdr : 8;
} t_dsmOpCode;
enum DSM_OPCODE{
DSM_MADD, DSM_INV, DSM_PUSH, DSM_POP, DSM_JG, DSM_DIE
};
*/
typedef SDL_Surface*(*SDL_SetVideoMode_t)(int, int, int, Uint32);
typedef int (*SDL_Flip_t)(SDL_Surface*);
typedef int (*SDL_LockSurface_t) (SDL_Surface *surface);
typedef void (*SDL_UnlockSurface_t) (SDL_Surface *surface);
typedef Uint32 (*SDL_MapRGB_t) (SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b);
typedef int (*SDL_PollEvent_t)(SDL_Event *event);
typedef Uint8* (*SDL_GetKeyState_t)(int *);
typedef void (*SDL_PumpEvents_t)(void);
typedef void* (*malloc_t) (size_t);
typedef int (*rand_t)(void);
typedef void (*srand_t)(unsigned int seed);
/****************************************************************************\
* here go the globals *
\****************************************************************************/
static t_pixel *g_fbuff;
static SDL_Surface *g_sdlbuff;
static unsigned int g_numXForms;
static t_xform *g_xforms;//[MAX_NUM_XFORMS+1]; //> "+1"=declare one more for use as temporary
static t_flameCoeff *g_flameCoeffs;//[MAX_NUM_XFORMS+1];//MAX_NUM_XFORMS+1];
static scalar *g_xformPBuffer;//[MAX_NUM_XFORMS+1];//> c above
#define FTMP g_xformPBuffer[MAX_NUM_XFORMS]
#define FTMP2 g_xformPBuffer[MAX_NUM_XFORMS-1]
static scalar g_scaleX, g_scaleY;
static SDL_Flip_t sym_SDL_Flip;
static SDL_LockSurface_t sym_SDL_LockSurface;
static SDL_UnlockSurface_t sym_SDL_UnlockSurface;
static SDL_MapRGB_t sym_SDL_MapRGB;
static rand_t sym_rand;
static srand_t sym_srand;
/****************************************************************************\
* here go the function defs *
\****************************************************************************/
/*--------------------------------------------------------------------------*\
* grabbed from http://rgba.scenesp.org/articles/sfrand/sfrand.htm/thx dudes*
\*--------------------------------------------------------------------------*/
/*
static unsigned int mirand = 1;
static float sfrand( void )
{
unsigned int a;
mirand *= 16807;
a = (mirand&0x007fffff) | 0x40000000;
return( *((float*)&a) - 3.0f );
}*/
#define initrand( x ) sym_srand( x )
#define sfrand( ) (((float)sym_rand()/(0.5*(float)RAND_MAX))-1.0)
#define frand( ) (((float)sym_rand()/(float)RAND_MAX))
#define urand() sym_rand()
/*--------------------------------------------------------------------------*\
* *
\*--------------------------------------------------------------------------*/
static inline void flushSurf( t_pixel *p_surf, int width, int height )
{
register unsigned int xy;
register unsigned int n = width*height;
for( xy=0; xy<n; xy++ ){
p_surf[ xy ].r =
p_surf[ xy ].g =
p_surf[ xy ].b =
p_surf[ xy ].density = 0;
}
}
/*--------------------------------------------------------------------------*\
* *
\*--------------------------------------------------------------------------*/
static inline void flipF2SDL( SDL_Surface *p_target, t_pixel *p_source, scalar scale, scalar densityScale )
{
if( SDL_MUSTLOCK(p_target) && sym_SDL_LockSurface(p_target)<0 )
return;
register unsigned int x,y,u;
for( y=0; y<p_target->h; y++ ){
Uint32 *bufp = (Uint32*)p_target->pixels + y*(p_target->pitch>>2);
t_pixel *source = p_source + y*p_target->w;
for( x=0; x<p_target->w; x++ ){
unsigned char c[3];
scalar D = 1+source->density*densityScale;
scalar d = (255 * scale * ( log(D)/D ));
//d = d * (0.7+0.3*cos(d*1.0));
for( u=0; u<3; u++ ){
scalar acc;
acc = source->m[u]*d;
acc = acc < 0 ? 0 :
acc > 255 ? 255 : acc;
c[u] = (unsigned char)acc;
}
*(bufp++) = sym_SDL_MapRGB(p_target->format, c[0], c[1], c[2] );
source++;
}
}
if( SDL_MUSTLOCK(p_target) )
sym_SDL_UnlockSurface(p_target);
sym_SDL_Flip(p_target);
}
/*--------------------------------------------------------------------------*\
* define random xforms for ifs *
\*--------------------------------------------------------------------------*/
static inline void defRandomXForms( int xseed, int cseed )
{
//> local vars
unsigned int u,v;//,w;
//> setup number of xforms scale
initrand( xseed );
g_numXForms = RANDOM_NUM_XFORMS;
//float rbuff[15];
t_xform *X = g_xforms;
FTMP = 0;
for( u=0; u<g_numXForms; X++, ++u ){
/* define random flame coefficients */
scalar flame = 0.0;
for( v=0; v<NUM_FLAME_COEFFICIENTS; v++ ){
g_flameCoeffs[u].coeff[v] = FLAME_RANDOM_COEFFICIENT;
flame += g_flameCoeffs[u].coeff[v]*g_flameCoeffs[u].coeff[v];
}
flame = sqrt( flame );
for( v=0; v<NUM_FLAME_COEFFICIENTS; v++ ){
g_flameCoeffs[u].coeff[v] /= flame;
}
//> random xform + rgb
for( v=0; v<6; v++ ){
X->m[v] = frand()-0.5;
}
//> init prob of this xform...
g_xformPBuffer[u] = frand();
FTMP += g_xformPBuffer[u];
/*
//> init prob of this xform...
//> define random flame coefficients
scalar flame = 0.0;//frand();
for( v=0; v<NUM_FLAME_COEFFICIENTS; v++ ){
g_flameCoeffs[u].coeff[v] = FLAME_RANDOM_COEFFICIENT;
flame += g_flameCoeffs[u].coeff[v]*g_flameCoeffs[u].coeff[v];
}
flame = 1./sqrt( flame );
for( v=0; v<NUM_FLAME_COEFFICIENTS; v++ ){
g_flameCoeffs[u].coeff[v] *= flame;
}
// define a random xform
for( v=0; v<15; rbuff[v++]=frand() )
;
//> random xform + rgb
for( v=0; v<6; v++ ){
X->m[v] = rbuff[v]-0.5;
}
// doh, too many bytes, removed! then, removed the rbuff[] cruft too.
if( rbuff[9]<ROT_PROB ){
X->x = 0;
X->y = 0;
if( rbuff[10]<TRANS_AFTER_ROT_PROB ){
X->x = TRANS_AFTER_ROT_SCALE*(rbuff[11]-0.5);
X->y = TRANS_AFTER_ROT_SCALE*(rbuff[12]-0.5);
}
scalar a = ROT_ADD + ROT_SCALE * rbuff[13]*(2*3.141f);//2.*3.14159);
X->y2 = -( X->x1 = sin(a));
X->y1 = ( X->x2 = cos(a));
}
//> init prob of this xform...
g_xformPBuffer[u] = rbuff[14];
FTMP += g_xformPBuffer[u];
*/
}
//> normalize probs
for( u=0; u<g_numXForms; u++ )
g_xformPBuffer[u] /= FTMP;
//> define random colors
/* define a random xform */
X = g_xforms;
initrand( cseed );
for( u=0; u<g_numXForms; ++X, ++u ){
X->r = frand()+0.25;
X->g = frand()+0.25;
X->b = frand()+0.25;
}
//> setup output scale
g_scaleX = 0.25;
g_scaleY = 0.25;
}
/*--------------------------------------------------------------------------*\
* burn it *
\*--------------------------------------------------------------------------*/
static inline void flame( scalar *px, scalar *py, t_flameCoeff *p_coeff )
{
static int num_flame_calls = 0;
num_flame_calls++;
const scalar pi = 3.14159;
const scalar x = *px;
const scalar y = *py;
scalar nx = 0;
scalar ny = 0;
const scalar r2 = ( *px * *px + *py * *py );
const scalar r = sqrt( r2 );
const scalar t = atan( *py / *px );
register scalar tr = t*r;
register scalar julia_omega = ((num_flame_calls&0x1)==0)?0:pi;
const scalar sin_r = sin(r);
const scalar cos_r = cos(r);
const scalar sin_t = sin(t);
const scalar cos_t = cos(t);
register scalar tmp;
const scalar EPSILON = 0.00;
/*static t_flameCoeff _coeff;
p_coeff = &_coeff;
//p_coeff->linear = 1.0;
//p_coeff->ex = 1.0;
//p_coeff->linear = 1.0;
p_coeff->polar = 1.0;
p_coeff->spherical = 2.5;
p_coeff->julia = 2.0;
p_coeff->disc = 2.8;
p_coeff->ex = 2;
//p_coeff->cust_hyperbolic = 0.7;//*/
// --- linear ---
if( p_coeff->linear > EPSILON ){
nx += p_coeff->linear * x;
ny += p_coeff->linear * y;
}
// --- sinusoidal ---
if( p_coeff->sinusoidal > EPSILON ){
nx += p_coeff->sinusoidal * sin( x );
ny += p_coeff->sinusoidal * sin( y );
}
// --- spherical ---
if( p_coeff->spherical > EPSILON ){
nx += p_coeff->spherical * x/r2;
ny += p_coeff->spherical * y/r2;
}
// --- swirl ---
if( p_coeff->swirl > EPSILON ){
nx += p_coeff->swirl * r*cos(t+r);
ny += p_coeff->swirl * r*sin(t+r);
}
// --- horseshoe ---
if( p_coeff->horseshoe > EPSILON ){
nx += p_coeff->horseshoe * r*cos(2*t);
ny += p_coeff->horseshoe * r*sin(2*t);
}
// --- polar ---
if( p_coeff->polar > EPSILON ){
nx += p_coeff->polar * (t / pi);
ny += p_coeff->polar * (r-1);
}
// --- handkerchief ---
if( p_coeff->handkerchief > EPSILON ){
nx += p_coeff->handkerchief * (r * sin(t+r));
ny += p_coeff->handkerchief * (cos(t-r));
}
// --- heart ---
if( p_coeff->heart > EPSILON ){
nx += p_coeff->heart * r * sin(tr);
ny += p_coeff->heart * -r * cos(tr);
}
// --- disc ---
if( p_coeff->disc > EPSILON ){
nx += p_coeff->disc * ( ( t * sin(pi*r) ) / pi );
ny += p_coeff->disc * ( ( t * cos(pi*r) ) / pi );
}
// --- spiral ---
if( p_coeff->spiral > EPSILON ){
nx += p_coeff->spiral * ( ( cos_t + sin_r ) / r );
ny += p_coeff->spiral * ( ( sin_t - cos_r ) / r );
}
// --- hyperbolic ---
if( p_coeff->hyperbolic > EPSILON ){
nx += p_coeff->hyperbolic * ( sin_t/r );
ny += p_coeff->hyperbolic * ( cos_t*r );
}
// --- diamond ---
if( p_coeff->diamond > EPSILON ){
nx += p_coeff->diamond * ( sin_t * cos_r );
ny += p_coeff->diamond * ( cos_t * sin_r );
}
// --- ex ---
if( p_coeff->ex > EPSILON ){
tmp = sin(t+r);
tmp *= tmp * tmp;
nx += p_coeff->ex * ( r * tmp );
tmp = cos(t-r);
tmp *= tmp * tmp;
ny += p_coeff->ex * ( r * tmp );
}
// --- julia ---
if( p_coeff->julia > EPSILON ){
nx += p_coeff->julia * ( sqrt(r) * cos( t/2 + julia_omega ) );
ny += p_coeff->julia * ( sqrt(r) * sin( t/2 + julia_omega ) );
}
// --- fisheye ---
if( p_coeff->fisheye > EPSILON ){
nx += p_coeff->fisheye * ((2*r)/(r+1))*x;
ny += p_coeff->fisheye * ((2*r)/(r+1))*y;
}
// --- cosine ---
if( p_coeff->cosine > EPSILON ){
// nx += p_coeff->cosine * cos(pi*x)*cosh(y);
// ny += p_coeff->cosine * -sin(pi*x)*sinh(y); //> not possible if we have no doubles
nx += p_coeff->cosine * cos(pi*x) * ( exp(y)+exp(-y) ) * 0.5;
ny += p_coeff->cosine * -sin(pi*x) * ( exp(y)-exp(-y) ) * 0.5;
}
// --- cust_hyperbolic ---
/*if( p_coeff->cust_hyperbolic > EPSILON ){
nx += p_coeff->cust_hyperbolic * ( sin(t)/r );
ny += p_coeff->cust_hyperbolic * ( cos(t)/r );
}*/
*px = nx;
*py = ny;
}
/*--------------------------------------------------------------------------*\
* samples the ifs *
\*--------------------------------------------------------------------------*/
static void moreSamples()
{
register unsigned int sample,length, xi, sx, sy;
scalar x,y, newx, newy;
scalar c[3];
for( sample=0; sample<SAMPLES_PER_CALL; sample++ ){
x = sfrand(); //> x = [-1..+1]
y = sfrand(); //> y = [-1..+1]*/
c[0] = 0;
c[1] = 0;//c[0];
c[2] = 0;//c[1];
for( length=0; length<MAX_SAMPLE_LENGTH; length++ ){
/* select xform */
newx = (sfrand()+1)*0.5;//> abusing newx
for( xi=0; (newx-=g_xformPBuffer[xi])>0; xi++ );
/* modify plotter color */
newx = 0.2; // abusing newx
newy = 1-newx; // abusing newy
c[0] = newx*c[0] + newy*g_xforms[xi].r;
c[1] = newx*c[1] + newy*g_xforms[xi].g;
c[2] = newx*c[2] + newy*g_xforms[xi].b;
/* multiply point with xform */
newx = (g_xforms[xi].x1*x + g_xforms[xi].x2*y + g_xforms[xi].x);
newy = (g_xforms[xi].y1*x + g_xforms[xi].y2*y + g_xforms[xi].y);
flame( &newx, &newy, &g_flameCoeffs[xi] );
x = newx;
y = newy;
/* scale to screen and plot */
sx = (int)( (x*g_scaleX) * (scalar)WIDTH ) + (WIDTH>>1);
sy = (int)( (y*g_scaleY) * (scalar)HEIGHT ) + (HEIGHT>>1);
if( length>DISCARD_SAMPLE_NUM
&& sx >= 0 && sx < WIDTH
&& sy >= 0 && sy < HEIGHT
){
t_pixel *pix = g_fbuff + sx+sy*WIDTH;
pix->m[0] += c[0];
pix->m[1] += c[1];
pix->m[2] += c[2];
pix->m[3] += 1.0;
}
}
}
}
/*--------------------------------------------------------------------------*\
* damn small itoa *
* returns pascal like string (for use as ´DUMPTEXT( ret+1, *ret )´) *
* where DUMPTEXT( [ptrToString], [length] ) *
\*--------------------------------------------------------------------------*/
static char *dsitoa( unsigned int num )
{
static char str[16];
char *tmp = str+15;
int num_digits = 0;
do{
num_digits++;
*tmp = num % 10 + '0';
tmp--;
}while( (num/=10)>0 );
*tmp = num_digits;
return tmp;
}
void _start()
{
//> jeep vars
unsigned int u;
//> load libs
void *libSDL = dlopen( "libSDL.so", RTLD_LAZY );
void *libC = dlopen( "libc.so", RTLD_LAZY );
#if 1
SDL_SetVideoMode_t sym_SDL_SetVideoMode = dlsym(libSDL, "SDL_SetVideoMode");
g_sdlbuff = sym_SDL_SetVideoMode(WIDTH,HEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
#else
((SDL_SetVideoMode_t)dlsym(libSDL, "SDL_SetVideoMode"))(WIDTH,HEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
#endif
//> need malloc, probably kinda craft (we only use it once :| )
//> load some sdl cruft (cruft!)
malloc_t sym_malloc = dlsym( libC, "malloc" );
sym_rand = dlsym( libC, "rand" );
sym_srand = dlsym( libC, "srand" );
sym_SDL_Flip = dlsym(libSDL, "SDL_Flip");
sym_SDL_LockSurface = dlsym(libSDL, "SDL_LockSurface");
sym_SDL_UnlockSurface = dlsym(libSDL, "SDL_UnlockSurface");
sym_SDL_MapRGB = dlsym(libSDL, "SDL_MapRGB");
Uint8 *keymap;
{
SDL_GetKeyState_t sym_SDL_GetKeyState = dlsym(libSDL, "SDL_GetKeyState");
keymap = sym_SDL_GetKeyState(0);
}
SDL_PumpEvents_t sym_SDL_PumpEvents = dlsym( libSDL, "SDL_PumpEvents" );
{
int A = sizeof(t_pixel)*WIDTH*HEIGHT;
int B = sizeof(t_xform) * (MAX_NUM_XFORMS+2);
int C = sizeof(t_flameCoeff) * (MAX_NUM_XFORMS+2);
int D = sizeof(scalar) * (MAX_NUM_XFORMS+2);
void *teh_mem = sym_malloc( A+B+C+D );
g_fbuff = (t_pixel*)teh_mem;
g_xforms = (t_xform*)(teh_mem+=A);
g_flameCoeffs = (t_flameCoeff*)(teh_mem+=B);
g_xformPBuffer = (scalar*)(teh_mem+C);
}
//> main loop goes here. it is pretty ugly
unsigned int frameNum = 0;
unsigned int xseed=666, cseed=222158903;
redefine:{
//xseed = frameNum>0 ? urand() : 666/*1714627440*/;
//cseed = frameNum>0 ? urand() : 222158903/*1910190196*/;
#if 0
char *tmp;
DUMPTEXT( "(", 1 );
tmp = dsitoa( frameNum ); DUMPTEXT( tmp+1, *tmp ); DUMPTEXT( "): x", 4 );
tmp = dsitoa( xseed ); DUMPTEXT( tmp+1, *tmp ); DUMPTEXT( ".c", 2 );
tmp = dsitoa( cseed ); DUMPTEXT( tmp+1, *tmp ); DUMPTEXT( ".bmp\n", 5 );
#endif
u=0;
defRandomXForms( xseed, cseed );
flushSurf( g_fbuff, WIDTH, HEIGHT );
frameNum++;
}
loop:{
sym_SDL_PumpEvents();
if( keymap[ SDLK_RETURN ] ){
initrand( frameNum );
xseed = urand();
goto redefine; // {goto afterloop} >> when you want to save your art*/
}
if( keymap[ SDLK_BACKSPACE ] ){
initrand( frameNum );
cseed = urand();
goto redefine; // {goto afterloop} >> when you want to save your art*/
}
if( keymap[ SDLK_ESCAPE ] )
BYEBYE();//goto byebye;
moreSamples();
flipF2SDL( g_sdlbuff, g_fbuff, 1.0, 7 ); //> around 350 bytes
}goto loop;
/*afterloop:
//SDL_SaveBMP( g_sdlbuff, "tmp.bmp" );
goto redefine;*/
byebye:
//atexit( SDL_QUIT );
BYEBYE();
}