/* Goom Project * Copyright (C) <2003> iOS-Software * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "lines.h" #include <math.h> #include <stdlib.h> #include <stdio.h> #include "goom_tools.h" #include "drawmethods.h" #include "goom_plugin_info.h" static inline unsigned char lighten (unsigned char value, float power) { int val = value; float t = (float) val * log10 (power) / 2.0; if (t > 0) { val = (int) t; /* (32.0f * log (t)); */ if (val > 255) val = 255; if (val < 0) val = 0; return val; } else { return 0; } } static void lightencolor (guint32 * 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); } static 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 = G_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 * G_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; } } static guint32 getcouleur (int mode) { switch (mode) { case GML_RED: return (230 << (ROUGE * 8)) | (120 << (VERT * 8)) | (18 << (BLEU * 8)); case GML_ORANGE_J: return (120 << (VERT * 8)) | (252 << (ROUGE * 8)) | (18 << (BLEU * 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)) | (18 << (BLEU * 8)); case GML_BLEU: return (250 << (BLEU * 8)) | (30 << (VERT * 8)) | (80 << (ROUGE * 8)); case GML_BLACK: return (16 << (BLEU * 8)) | (16 << (VERT * 8)) | (16 << (ROUGE * 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); } } static 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.1f) { l->power = 1.1f; l->powinc = (float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f; } if (l->power > 17.5f) { l->power = 17.5f; l->powinc = -(float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f; } l->amplitude = (99.0f * l->amplitude + l->amplitudeF) / 100.0f; } void goom_lines_switch_to (GMLine * gml, int IDdest, float param, float amplitude, int col) { genline (IDdest, param, gml->points2, gml->screenX, gml->screenY); gml->IDdest = IDdest; gml->param = param; gml->amplitudeF = amplitude; gml->color2 = getcouleur (col); } GMLine * goom_lines_init (PluginInfo * goomInfo, int rx, int ry, int IDsrc, float paramS, int coulS, int IDdest, float paramD, int coulD) { GMLine *l = (GMLine *) malloc (sizeof (GMLine)); l->goomInfo = goomInfo; l->points = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer)); l->points2 = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer)); l->nbPoints = 512; l->IDdest = IDdest; l->param = paramD; l->amplitude = l->amplitudeF = 1.0f; 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, 1.0f, coulD); return l; } void goom_lines_free (GMLine ** l) { free ((*l)->points2); free ((*l)->points); free (*l); l = NULL; } void goom_lines_draw (PluginInfo * plug, GMLine * line, gint16 data[512], Pixel * 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 * line->amplitude * data[0]); y1 = (int) (pt->y + sina * line->amplitude * 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 * line->amplitude * data[i]); y2 = (int) (pt->y + sina * line->amplitude * data[i]); plug->methods.draw_line (p, x1, y1, x2, y2, color, line->screenX, line->screenY); x1 = x2; y1 = y2; } goom_lines_move (line); } }