synkro
0xdeadbeef
still some warnings, but it works... finally...
Code:
/*
* BASIC DYNAMIC PLASMA
* --------------------
*
* + precalculated cosine table
* + 16bit graphic mode
* + enabled 16bit TextOut (thx to Charge an the almighty Mr. Spiv)
*
* [intro]
* You all have seen it many times, but many people
* still ask themselvs "How does that friggin plasma work
* at all?" Please excuse my bad english, but I will try
* to explain the classic to you on the GP32.
*
* [theory]
* We will do some dynamic plasma, not a static one because
* that is just some clever palatte cycling, but we will
* work in 16bit anyway.
* We have to calculate cosine, because we need some nice
* curves, but cosine is rather slow for realtime so we
* have to pre-calculate it in a table. I use
* 1220 * (cos(i * M_PI / 64)) as my formula, because
* 1220 sets some nice colors and 64 a good size of the "blops"
*
* So we calculate a 256 long cosine table:
*
* int cosinus[256];
* for (i=0; i<256; i++)
* cosinus[i] = 1220 * (cos(i * M_PI / 64));
*
* What do we need the cosine for? We want to draw some
* nice cruves, so we need two cosine for vertical and
* horizontal movement. You have to define p1, p2, p3, p4
* for the movement and t1, t2, t3, t4 to store the original
* cosine as undefined chars, because they will be the index
* for the cosine table.
*
* Now to the main function. p1 and p2 are for the vertical
* and p3, p4 for the horizontal movement and the t1,t2,t3,t4
* are the temp var of the p's.
*
* Store p1,p2 before you enter the loop for the y-axis, the
* same for p3,p4 and the x-axis.
*
* t1 = p1;
* t2 = p2;
* for (i = 0; i < y-lenght; i++)
* t3 = p3;
* t4 = p4;
* for (j = 0; j < x-length; j++)
*
* Y-lenght and x-lenght are the size of the tile we draw
* over the screen, I use 128px as tile size.
* No we put the cosine into the loops. We have to
* calculate every color of every pixel including each
* movement.
*
* color[y][x] = cosinus[t1] + cosinus[t2]
* + cosinus[t3] + cosinus[t4]
*
* Now you can blit the color array on the screen. After
* each loop you have to change t3,t4 in the x loop
* and then t1,t2 in the y loop. After both loops change
* p1,p2,p3,p4 to achieve any kind of movement you want!
* That's it!
*
* [outro]
* I hope you understood at least a bit and this tuto is
* in anyway useful to you. In the following code the
* plasma has been optimized by me, but is far from perfect.
* Feel free to fool around with the code and formula to
* get some nice effects (there is more than cosine ).
* The is also a fps counter, so can check if your
* optimaziations really speed up the plasma.
*
* If you have any problems, questions or c/C then try
* to cantact me (or the other guys and gals) at #gp32dev
* or www.gp32x.de.
*
* by synkro 15.02.2004 14:53:26
*/
// GP SDK Includes
#include "gpdef.h"
#include "gpstdlib.h"
#include "gpgraphic.h"
#include "gpgraphic16.h"
#include "gpfont.h"
#include "gpfont16.h"
#include "gpmain.h"
// Extra Includes
#include <math.h>
// Size of the plasma tile
#define _TILE 128
// Create 2 graphic buffers
GPDRAWSURFACE gpDraw[2];
BGFONTINFO FontInfo;
// Flipper for the graphic buffers
int nflip;
void GpMain(void *arg)
{
int i, j, temp;
unsigned short color[_TILE][_TILE];
int cosinus[256];
unsigned char p1,p2,p3,p4,t1,t2,t3,t4;
char text[32];
// set screen into 16bit mode
GpGraphicModeSet (16, NULL);
// create 2 buffer pages
for(i = 0; i < 2; i++)
{
GpLcdSurfaceGet(&gpDraw[i], i);
}
GpSurfaceSet(&gpDraw[0]);
// re-config of the fontinfo to enable 16bit textout
FontInfo.kor_w = 8;
FontInfo.kor_h = 8;
FontInfo.eng_w = 8;
FontInfo.eng_h = 16;
FontInfo.chargap = 10;
FontInfo.linegap = 10;
GpFontInit(&FontInfo);
GpFontInit16(&FontInfo);
// precalculate Cosine table
// You can fool around with the constants and the
// formula to achieve different effects.
for (i=0; i<256; i++)
cosinus[i] = 1220 * (cos(i * M_PI / 64));
nflip = 0;
while(1)
{
t1 = p1;
t2 = p2;
for (i = 0; i < _TILE; i++)
{
t3 = p3;
t4 = p4;
temp = cosinus[t1] + cosinus[t2];
for (j = 0; j < _TILE; j++)
{
color[j][i] = temp + cosinus[t3] + cosinus[t4];
t3+=1;
t4+=3;
}
t1+=2;
t2+=1;
}
p1+=1;
p2-=2;
p3+=3;
p4-=1;
// draw the tiles over the screen
for (i=0; i<2; i++)
{
for (j=0; j<3; j++)
{
GpBitBlt16(NULL, &gpDraw[nflip], j*_TILE, i*_TILE, _TILE, _TILE, *color, 0, 0, _TILE, _TILE);
}
}
// Show current FPS on screen
// gm_sprintf(text, "FPS: %i", CountFPS());
sprintf(text, "FPS: %i", CountFPS());
GpTextOut16(NULL, &gpDraw[nflip], 10, 10, text, 0xFFFF);
// Flip graphic buffer
GpSurfaceFlip(&gpDraw[nflip++]);
nflip &= 0x01;
}
}
/*
* Counts frames per second
*/
CountFPS()
{
static long time = 0;
static short fps = 0, fps_count = 0;
long tick = GpTickCountGet();
fps++;
if(tick > (time + 1000))
{
time = tick;
fps_count = fps;
fps = 0;
}
return fps_count;
}
Last edited by a moderator: