/*
* $Id: frag.c 264 2005-11-06 17:43:44Z mrbrown $
*
* Copyright 2003 Kenta Cho. All rights reserved.
*/
/**
* Fragments.
*
* @version $Revision: 264 $
*/
#include "genmcr.h"
#include "screen.h"
#include "vector.h"
#include "degutil.h"
#include "ship.h"
#include "frag.h"
Frag frag[FRAG_MAX];
static int fragIdx;
void initFrags() {
int i;
for ( i=0 ; i<FRAG_MAX ; i++ ) {
frag[i].cnt = 0;
}
fragIdx = FRAG_MAX;
}
static int fragColors[][3] = {
{100, 255, 100}, {240, 240, 240},
{240, 240, 120}, {255, 255, 255},
{128, 128, 128}, {255, 255, 255},
{100, 100, 255}, {220, 220, 200},
};
#define FRAG_LINE 0
static void addLineFrag(int x, int y, int z, int mx, int my, int mz,
int width, int d1, int cp, int cnt) {
int i;
Frag *fr;
for ( i=0 ; i<FRAG_MAX ; i++ ) {
fragIdx--; if ( fragIdx < 0 ) fragIdx = FRAG_MAX-1;
if ( frag[fragIdx].cnt <= 0 ) break;
}
if ( i >= FRAG_MAX ) return;
fr = &(frag[fragIdx]);
fr->x = x / FIELD_SCREEN_RATIO;
fr->y = y / FIELD_SCREEN_RATIO;
fr->z = z / FIELD_SCREEN_RATIO;
fr->mx = mx / FIELD_SCREEN_RATIO;
fr->my = my / FIELD_SCREEN_RATIO;
fr->mz = mz / FIELD_SCREEN_RATIO;
fr->width = width / FIELD_SCREEN_RATIO;
fr->d1 = d1; fr->d2 = 0;
fr->md1 = randNS(32); fr->md2 = randNS(32);
for ( i=0 ; i<FRAG_COLOR_NUM ; i++ ){
fr->r[i] = fragColors[cp+i][0];
fr->g[i] = fragColors[cp+i][1];
fr->b[i] = fragColors[cp+i][2];
}
fr->cnt = cnt;
}
static void addLineFragFloat(float x, float y, float z, int mx, int my, int mz,
float width, int d1, int cp, int cnt) {
int i;
Frag *fr;
for ( i=0 ; i<FRAG_MAX ; i++ ) {
fragIdx--; if ( fragIdx < 0 ) fragIdx = FRAG_MAX-1;
if ( frag[fragIdx].cnt <= 0 ) break;
}
if ( i >= FRAG_MAX ) return;
fr = &(frag[fragIdx]);
fr->x = x;
fr->y = y;
fr->z = z;
fr->mx = mx / FIELD_SCREEN_RATIO;
fr->my = my / FIELD_SCREEN_RATIO;
fr->mz = mz / FIELD_SCREEN_RATIO;
fr->width = width;
fr->d1 = d1; fr->d2 = 0;
fr->md1 = randNS(5); fr->md2 = randNS(5);
for ( i=0 ; i<FRAG_COLOR_NUM ; i++ ){
fr->r[i] = fragColors[cp+i][0];
fr->g[i] = fragColors[cp+i][1];
fr->b[i] = fragColors[cp+i][2];
}
fr->cnt = cnt;
}
void addLaserFrag(int x, int y, int width) {
int wd = width/4;
int i;
int lx = x - width/4*3;
for ( i=0 ; i<4 ; i++, lx += width/2 ) {
addLineFrag(lx, y, 0, randNS(512), 512+randN(512), randNS(256), wd, 256, 0, 10+randN(10));
addLineFrag(lx, y, 0, randNS(512), 512+randN(512), randNS(256), wd, 0, 0, 10+randN(10));
}
}
void addBossFrag(float x, float y, float z, float width, int d) {
addLineFragFloat(x, y, z, randNS(1024), randNS(1024), randNS(1024),
width, d, 2, 52+randN(20));
}
void addShipFrag(float x, float y) {
int i, d, s;
for ( i=0 ; i<80 ; i++ ) {
d = randN(1024);
s = randN(128)+128;
addLineFragFloat(x, y, 0, (sctbl[d]*s)>>6, (sctbl[d+256]*s)>>6, randNS(1024),
0.5f, -d&1023, 0, 24+randN(12));
}
}
void addGrazeFrag(int x, int y, int mx, int my) {
int d = getDeg(mx, -my);
addLineFrag(x, -y, 0, (mx>>2), (-my>>2), randNS(1024), 5000, d, 6, 16);
addLineFrag(x, -y, 0, (mx>>2), (-my>>2), randNS(1024), 2500, d, 6, 10);
}
void addLineFragOfs(GLfloat x, GLfloat y, GLfloat ox1, GLfloat oy1, GLfloat ox2, GLfloat oy2,
int d,
int mx, int my) {
GLfloat cx, cy, ox, oy, lw;
int ld;
ox = (ox1+ox2)/2; oy = (oy1+oy2)/2;
d = -d; d &= 1023;
cx = (ox*sctbl[d+256] - oy*sctbl[d]) / 256.0f + x;
cy = (ox*sctbl[d] + oy*sctbl[d+256]) / 256.0f + y;
ld = (getDeg((int)((ox1-ox2)*256), (int)((oy1-oy2)*256)) + d) & 1023;
lw = getDistanceFloat(ox2-ox1, oy2-oy1)/2;
addLineFragFloat(cx, cy, 0, mx, -my, -randN(1024)-1024, lw, ld, 4, 24+randN(16));
}
void addShapeFrag(GLfloat x, GLfloat y, GLfloat size, int d, int cnt, int type, int mx, int my) {
int sd;
GLfloat sz, sz2;
switch ( type ) {
case -1:
sz = size/2;
addLineFragOfs(x, y, 0, -sz, 0, sz, d, mx, my);
break;
case 0:
sz = size/2;
addLineFragOfs(x, y, -sz, -sz, sz, -sz, d, mx, my);
addLineFragOfs(x, y, sz, -sz, 0, size, d, mx, my);
addLineFragOfs(x, y, 0, size, -sz, -sz, d, mx, my);
break;
case 1:
sz = size/2;
sd = (cnt*23)&1023;
addLineFragOfs(x, y, 0, -size, sz, 0, sd, mx, my);
addLineFragOfs(x, y, sz, 0, 0, size, sd, mx, my);
addLineFragOfs(x, y, 0, size, -sz, 0, sd, mx, my);
addLineFragOfs(x, y, -sz, 0, 0, -size, sd, mx, my);
break;
case 2:
sz = size/4; sz2 = size/3*2;
addLineFragOfs(x, y, -sz, -sz2, sz, -sz2, d, mx, my);
addLineFragOfs(x, y, sz, -sz2, sz, sz2 ,d, mx, my);
addLineFragOfs(x, y, sz, sz2, -sz, sz2, d, mx, my);
addLineFragOfs(x, y, -sz, sz2, -sz, -sz2, d, mx, my);
break;
case 3:
sz = size/2;
sd = (cnt*37)&1023;
addLineFragOfs(x, y, -sz, -sz, sz, -sz, sd, mx, my);
addLineFragOfs(x, y, sz, -sz, sz, sz ,sd, mx, my);
addLineFragOfs(x, y, sz, sz, -sz, sz, sd, mx, my);
addLineFragOfs(x, y, -sz, sz, -sz, -sz, sd, mx, my);
break;
case 4:
sz = size/2;
sd = (cnt*53)&1023;
addLineFragOfs(x, y, -sz/2, -sz, sz/2, -sz, sd, mx, my);
addLineFragOfs(x, y, sz/2, -sz, sz, -sz/2, sd, mx, my);
addLineFragOfs(x, y, sz, -sz/2, sz, sz/2, sd, mx, my);
addLineFragOfs(x, y, sz, sz/2, -sz/2, sz, sd, mx, my);
addLineFragOfs(x, y, -sz/2, sz, -sz, sz/2, sd, mx, my);
addLineFragOfs(x, y, -sz, sz/2, -sz, -sz/2, sd, mx, my);
break;
case 5:
sz = size*2/3; sz2 = size/5;
addLineFragOfs(x, y, -sz, -sz+sz2, sz, -sz+sz2, d, mx, my);
addLineFragOfs(x, y, sz, -sz+sz2, 0, sz+sz2, d, mx, my);
addLineFragOfs(x, y, 0, sz+sz2, -sz, -sz+sz2, d, mx, my);
break;
case 6:
sz = size/2;
sd = (cnt*13)&1023;
addLineFragOfs(x, y, -sz, -sz, 0, -sz, sd, mx, my);
addLineFragOfs(x, y, 0, -sz, sz, 0, sd, mx, my);
addLineFragOfs(x, y, sz, 0, sz, sz, sd, mx, my);
addLineFragOfs(x, y, sz, sz, 0, sz, sd, mx, my);
addLineFragOfs(x, y, 0, sz, -sz, 0, sd, mx, my);
addLineFragOfs(x, y, -sz, 0, -sz, -sz, sd, mx, my);
break;
}
}
void moveFrags() {
int i;
Frag *fr;
for ( i=0 ; i<FRAG_MAX ; i++ ) {
if ( frag[i].cnt <= 0 ) continue;
fr = &(frag[i]);
fr->x += fr->mx;
fr->y += fr->my;
fr->z += fr->mz;
fr->d1 += fr->md1;
fr->d2 += fr->md2;
fr->d1 &= 1023; fr->d2 &= 1023;
fr->cnt--;
}
}
void drawFrags() {
int c;
int i;
Frag *fr;
for ( i=0 ; i<FRAG_MAX ; i++ ) {
if ( frag[i].cnt <= 0 ) continue;
fr = &(frag[i]);
c = fr->cnt&(FRAG_COLOR_NUM-1);
drawRollLine(fr->x, fr->y, fr->z, fr->width,
fr->r[c], fr->g[c], fr->b[c], 255, fr->d1, fr->d2);
}
}