summaryrefslogtreecommitdiff
path: root/src/post/goom/lines.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/post/goom/lines.c')
-rw-r--r--src/post/goom/lines.c465
1 files changed, 465 insertions, 0 deletions
diff --git a/src/post/goom/lines.c b/src/post/goom/lines.c
new file mode 100644
index 000000000..72ce65342
--- /dev/null
+++ b/src/post/goom/lines.c
@@ -0,0 +1,465 @@
+/*
+ * lines.c
+ * iTunesXPlugIn
+ *
+ * Created by guillaum on Tue Aug 14 2001.
+ * Copyright (c) 2001 __CompanyName__. All rights reserved.
+ *
+ */
+
+#include "lines.h"
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "goom_tools.h"
+
+extern unsigned int resolx,c_resoly;
+
+#define DRAWMETHOD_NORMAL *p = col
+
+#define DRAWMETHOD_PLUS \
+{\
+ int dra=0,i=0;\
+ unsigned char *tra = (unsigned char*)p;\
+ unsigned char *cra = (unsigned char*)&col;\
+ for (;i<4;i++) {\
+ dra = *cra;\
+ dra += *tra;\
+ if (dra>255) dra=255;\
+ *tra = dra;\
+ ++tra;++cra;\
+ }\
+}
+
+#define DRAWMETHOD_DEMIPLUS \
+{\
+ int dra=0,i=0;\
+ unsigned char *tra = (unsigned char*)p;\
+ unsigned char *cra = (unsigned char*)&col;\
+ for (;i<4;i++) {\
+ dra = *cra >> 1;\
+ dra += *tra;\
+ if (dra>255) dra=255;\
+ *tra = dra;\
+ ++tra;++cra;\
+ }\
+}
+
+#define DRAWMETHOD_OR *p|=col
+
+#define DRAWMETHOD {DRAWMETHOD_DEMIPLUS; DRAWMETHOD_OR;}
+
+static void draw_line (int *data, int x1,int y1,int x2,int y2, int col, int screenx, int screeny) {
+ int x, y, dx, dy, yy, xx;
+ int *p;
+// DATA32 *p;
+// DATA8 aaa, nr, ng, nb, rr, gg, bb, aa, na;
+
+ /* clip to top edge */
+ if ((y1 < 0) && (y2 < 0))
+ return;
+ if (y1 < 0)
+ {
+ x1 += (y1 * (x1 - x2)) / (y2 - y1);
+ y1 = 0;
+ }
+ if (y2 < 0)
+ {
+ x2 += (y2 * (x1 - x2)) / (y2 - y1);
+ y2 = 0;
+ }
+ /* clip to bottom edge */
+ if ((y1 >= screeny) && (y2 >= screeny))
+ return;
+ if (y1 >= screeny)
+ {
+ x1 -= ((screeny - y1) * (x1 - x2)) / (y2 - y1);
+ y1 = screeny - 1;
+ }
+ if (y2 >= screeny)
+ {
+ x2 -= ((screeny - y2) * (x1 - x2)) / (y2 - y1);
+ y2 = screeny - 1;
+ }
+ /* clip to left edge */
+ if ((x1 < 0) && (x2 < 0))
+ return;
+ if (x1 < 0)
+ {
+ y1 += (x1 * (y1 - y2)) / (x2 - x1);
+ x1 = 0;
+ }
+ if (x2 < 0)
+ {
+ y2 += (x2 * (y1 - y2)) / (x2 - x1);
+ x2 = 0;
+ }
+ /* clip to right edge */
+ if ((x1 >= screenx) && (x2 >= screenx))
+ return;
+ if (x1 >= screenx)
+ {
+ y1 -= ((screenx - x1) * (y1 - y2)) / (x2 - x1);
+ x1 = screenx - 1;
+ }
+ if (x2 >= screenx)
+ {
+ y2 -= ((screenx - x2) * (y1 - y2)) / (x2 - x1);
+ x2 = screenx - 1;
+ }
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (x1 > x2)
+ {
+ int tmp;
+
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ dx = x2 - x1;
+ dy = y2 - y1;
+ }
+
+ /* vertical line */
+ if (dx == 0)
+ {
+ if (y1 < y2)
+ {
+ p = &(data[(screenx * y1) + x1]);
+ for (y = y1; y <= y2; y++)
+ {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ else
+ {
+ p = &(data[(screenx * y2) + x1]);
+ for (y = y2; y <= y1; y++)
+ {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ return;
+ }
+ /* horizontal line */
+ if (dy == 0)
+ {
+ if (x1 < x2)
+ {
+ p = &(data[(screenx * y1) + x1]);
+ for (x = x1; x <= x2; x++)
+ {
+ DRAWMETHOD;
+ p++;
+ }
+ return;
+ }
+ else
+ {
+ p = &(data[(screenx * y1) + x2]);
+ for (x = x2; x <= x1; x++)
+ {
+ DRAWMETHOD;
+ p++;
+ }
+ return;
+ }
+ }
+ /* 1 */
+ /* \ */
+ /* \ */
+ /* 2 */
+ if (y2 > y1)
+ {
+ /* steep */
+ if (dy > dx)
+ {
+ dx = ((dx << 16) / dy);
+ x = x1 << 16;
+ for (y = y1; y <= y2; y++)
+ {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1))
+ {
+ p++;
+// DRAWMETHOD;
+ }
+ x += dx;
+ }
+ return;
+ }
+ /* shallow */
+ else
+ {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++)
+ {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1))
+ {
+ p += screeny;
+// DRAWMETHOD;
+ }
+ y += dy;
+ }
+ }
+ }
+ /* 2 */
+ /* / */
+ /* / */
+ /* 1 */
+ else
+ {
+ /* steep */
+ if (-dy > dx)
+ {
+ dx = ((dx << 16) / -dy);
+ x = (x1 + 1) << 16;
+ for (y = y1; y >= y2; y--)
+ {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1))
+ {
+ p--;
+// DRAWMETHOD;
+ }
+ x += dx;
+ }
+ return;
+ }
+ /* shallow */
+ else
+ {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++)
+ {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1))
+ {
+ p += screeny;
+// DRAWMETHOD;
+ }
+ y += dy;
+ }
+ return;
+ }
+ }
+}
+
+void genline (int id, float param, GMUnitPointer *l, int rx, int ry) {
+ int i;
+ switch (id) {
+ case GML_HLINE:
+ for (i = 0; i < 512; i++) {
+ l [i].x = ((float)i * rx) / 512.0f;
+ l [i].y = param;
+ l [i].angle = M_PI / 2.0f;
+ }
+ return;
+ case GML_VLINE:
+ for (i = 0; i < 512; i++) {
+ l [i].y = ((float)i * ry) / 512.0f;
+ l [i].x = param;
+ l [i].angle = 0.0f;
+ }
+ return;
+ case GML_CIRCLE:
+ for (i = 0; i < 512; i++) {
+ float cosa,sina;
+ l [i].angle = 2.0f*M_PI*(float)i / 512.0f;
+ cosa = param * cos(l[i].angle);
+ sina = param * sin(l[i].angle);
+ l [i].x = ((float)rx / 2.0f) + cosa;
+ l [i].y = (float)ry / 2.0f + sina;
+ }
+ return;
+ }
+}
+
+guint32 getcouleur (int mode) {
+ switch (mode) {
+ case GML_RED:
+ return (230 << (ROUGE * 8)) | (120 << (VERT * 8));
+ case GML_ORANGE_J:
+ return (120 << (VERT * 8)) | (252 << (ROUGE * 8));
+ case GML_ORANGE_V:
+ return (160 << (VERT * 8)) | (236 << (ROUGE * 8)) | (40 << (BLEU * 8));
+ case GML_BLEUBLANC:
+ return (40 << (BLEU * 8)) | (220 << (ROUGE * 8)) | (140 << (VERT * 8));
+ case GML_VERT:
+ return (200 << (VERT*8)) | (80 << (ROUGE*8));
+ case GML_BLEU:
+ return (250 << (BLEU*8)) | (30 << (VERT*8)) | (80 << (ROUGE*8));
+ case GML_BLACK:
+ return 0x10 << (BLEU*8);
+ }
+ return 0;
+}
+
+void goom_lines_set_res (GMLine *gml, int rx, int ry) {
+ if (gml != NULL) {
+
+ gml->screenX = rx;
+ gml->screenY = ry;
+
+ genline (gml->IDdest, gml->param, gml->points2, rx,ry);
+ }
+}
+
+
+void goom_lines_move (GMLine *l) {
+ int i;
+ unsigned char *c1,*c2;
+
+ for (i = 0; i < 512; i++) {
+ l->points [i].x = (l->points2 [i].x + 39.0f * l->points [i].x) / 40.0f;
+ l->points [i].y = (l->points2 [i].y + 39.0f * l->points [i].y) / 40.0f;
+ l->points [i].angle = (l->points2 [i].angle + 39.0f * l->points [i].angle) / 40.0f;
+ }
+
+ c1 = (unsigned char*)&l->color;
+ c2 = (unsigned char*)&l->color2;
+ for (i=0;i<4;i++) {
+ int cc1,cc2;
+ cc1 = *c1;
+ cc2 = *c2;
+ *c1 = (unsigned char) ((cc1 * 63 + cc2) >> 6 );
+ ++c1;++c2;
+ }
+
+ l->power += l->powinc;
+ if (l->power < -1.6f) {
+ l->power = -1.6f;
+ l->powinc = (float)(iRAND(20) + 10) / 600.0f;
+ }
+ if (l->power > 1.0f) {
+ l->power = 1.0f;
+ l->powinc = - (float)(iRAND(20) + 10) / 600.0f;
+ }
+}
+
+void goom_lines_switch_to (GMLine *gml, int IDdest, float param, int col) {
+ genline (IDdest, param, gml->points2, gml->screenX,gml->screenY);
+ gml->IDdest = IDdest;
+ gml->param = param;
+ gml->color2 = getcouleur (col);
+// printf ("couleur %d : %x\n",col,gml->color2);
+}
+
+inline unsigned char lighten(unsigned char value,float power)
+{
+ int val = value;
+ float t = exp ((float)val / 64.0f) + power;
+ if (t > 0) {
+ val = (int)(64.0f * log (t));
+ if (val > 255)
+ val = 255;
+ if (val < 0)
+ val=0;
+ return val;
+ }
+ else {
+ return 0;
+ }
+}
+
+void lightencolor (int *col, float power) {
+ unsigned char *color;
+ color = (unsigned char *)col;
+ * color = lighten(*color,power);
+ color++;
+ * color = lighten(*color,power);
+ color++;
+ * color = lighten(*color,power);
+ color++;
+ * color = lighten(*color,power);
+}
+
+GMLine* goom_lines_init (int rx,int ry,
+ int IDsrc, float paramS,int coulS,
+ int IDdest, float paramD, int coulD)
+{
+
+ GMLine *l = (GMLine*)malloc(sizeof(GMLine));
+
+ l->points = (GMUnitPointer*)malloc(512*sizeof(GMUnitPointer));
+ l->points2 = (GMUnitPointer*)malloc(512*sizeof(GMUnitPointer));
+ l->nbPoints = 512;
+
+ l->IDdest = IDdest;
+ l->param = paramD;
+
+ genline (IDsrc, paramS, l->points, rx,ry);
+ genline (IDdest, paramD, l->points2, rx,ry);
+
+ l->color = getcouleur (coulS);
+ l->color2 = getcouleur (coulD);
+
+ l->screenX = rx;
+ l->screenY = ry;
+
+ l->power = 0.0f;
+ l->powinc = 0.01f;
+
+ goom_lines_switch_to (l, IDdest, paramD, coulD);
+
+ return l;
+}
+
+void goom_lines_free (GMLine **l) {
+ free ((*l)->points);
+ free (*l);
+ l = NULL;
+}
+
+void goom_lines_draw(GMLine *line,
+ gint16 data [512],
+ unsigned int* p)
+
+{
+ if (line != NULL) {
+ int i,x1,y1;
+ guint32 color = line->color;
+ GMUnitPointer *pt = &(line->points[0]);
+
+ float cosa = cos(pt->angle) / 1000.0f;
+ float sina = sin(pt->angle) / 1000.0f;
+
+ lightencolor (&color, line->power);
+
+ x1 = (int) (pt->x + cosa * data[0]);
+ y1 = (int) (pt->y + sina * data[0]);
+
+ for (i=1;i<512;i++) {
+ int x2,y2;
+ GMUnitPointer *pt = &(line->points[i]);
+
+ float cosa = cos(pt->angle) / 1000.0f;
+ float sina = sin(pt->angle) / 1000.0f;
+
+ x2 = (int) (pt->x + cosa * data[i]);
+ y2 = (int) (pt->y + sina * data[i]);
+
+ draw_line (p, x1,y1,x2,y2,color,line->screenX,line->screenY);
+ x1=x2;
+ y1=y2;
+ }
+ goom_lines_move (line);
+ }
+}
+