Logo Search packages:      
Sourcecode: kdeaddons version File versions

display.c

/*
// Copyright (C) 2000 Julien Carme
// Copyright (C) 2001 Neil Stevens <neil@qualityassistant.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2, as
// published by the Free Software Foundation.
//
// 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
*/

#include "renderer.h"
#include "main.h"
#include "display.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include <SDL.h>


SDL_Color color_table[NB_PALETTES][256];
short current_colors[256];

byte* surface1;
byte* surface2;

void generate_colors(void)
{
      int i,k;
      float colors[NB_PALETTES][2][3]={{{1,1,1},{1,1,1}},
                               {{2,1.5,0},{0,0.5,2}},
                               {{0,1,2},{0,1,0}},
                               {{0,2,1},{0,0,1}},
                               {{2,0,0},{0,1,1}}};

      for (k=0;k<NB_PALETTES;k++)
      {
            for ( i=0; i<128; i++ )
            {
                  color_table[k][i].r = colors[k][0][0]*i;
                  color_table[k][i].g = colors[k][0][1]*i;
                  color_table[k][i].b = colors[k][0][2]*i;
            }

            for ( i=0; i<128; i++ )
            {
                  color_table[k][i+128].r = colors[k][0][0]*127+colors[k][1][0]*i;
                  color_table[k][i+128].g = colors[k][0][1]*127+colors[k][1][1]*i;
                  color_table[k][i+128].b = colors[k][0][2]*127+colors[k][1][2]*i;
            }
      }
}

void change_color(int t2,int t1,int w)
{
      unsigned int i;

      for (i=0;i<255;i++)
      {
            int r,g,b;
            r = (color_table[t1][i].r*w+color_table[t2][i].r*(256-w) )>>11;
            g = (color_table[t1][i].g*w+color_table[t2][i].g*(256-w) )>>10;
            b = (color_table[t1][i].b*w+color_table[t2][i].b*(256-w) )>>11;
            current_colors[i]=(r<<11)+(g<<5)+b;
      }
}

void compute_surface(t_interpol* vector_field)
{
      int i,j;
      int add_dest=0;
      int add_src;
      t_interpol *interpol;
      register byte* ptr_pix;
      int color;
      byte* ptr_swap;

      for (j=0;j<scr_par.height;j++)
      {
            for (i=0;i<scr_par.width;i++)
            {
                  interpol=&vector_field[add_dest];
                  add_src=(interpol->coord & 0xFFFF)*scr_par.width+(interpol->coord>>16);
                  ptr_pix=&((byte*)surface1)[add_src];
                  color=(*(ptr_pix)*(interpol->weight>>24)
                         +*(ptr_pix+1)*((interpol->weight & 0xFFFFFF)>>16)
                         +*(ptr_pix+scr_par.width)*((interpol->weight & 0xFFFF)>>8)
                         +*(ptr_pix+scr_par.width+1)*(interpol->weight & 0xFF))>>8;

                  if (color>255)
                        surface2[add_dest]=255;
                  else
                        surface2[add_dest]=color;
                  add_dest++;
            }
      }

      ptr_swap=surface1;
      surface1=surface2;
      surface2=ptr_swap;
}

void display_surface(void)
{
      int i,j;

      if (scr_par.scale>1)
      {
            for (i=0;i<scr_par.height;i++)
            {
                  short* pdest=(short*)(screen->pixels+i*screen->pitch*scr_par.scale);
                  byte* psrc=surface1+i*scr_par.width;

                  if (scr_par.scale==2)
                  {
                        for (j=1; j<scr_par.width; j++)
                        {
                              *(pdest++) = current_colors[*psrc++];
                              *(pdest++) = *(pdest-1);
                        }

                        memcpy(screen->pixels+i*screen->pitch*2+screen->pitch,
                              screen->pixels+i*screen->pitch*2,screen->pitch);
                  }
/*              else
                {
                  for (j=1;j<scr_par.width;j++) {
                      *(pdest++)=current_colors[*psrc++];
                      *(pdest++)=*(pdest-1);
                      *(pdest++)=*(pdest-1);
                  }
                  memcpy(screen->pixels+i*screen->pitch*3+screen->pitch,
                         screen->pixels+i*screen->pitch*3,screen->pitch);
                  memcpy(screen->pixels+i*screen->pitch*3+screen->pitch*2,
                         screen->pixels+i*screen->pitch*3,screen->pitch);

                }
*/
            }
      }
      else
      {
            byte* psrc=surface1;
            for (i=0;i<scr_par.height;i++)
            {
                  short* pdest=(short*)(screen->pixels+i*screen->pitch);
                  for (j=0;j<scr_par.width;j++)
                  *pdest++=current_colors[*psrc++];
            }
      }
      SDL_UpdateRect(screen, 0, 0, 0, 0);
}

void blur(t_interpol* vector_field)
{
      compute_surface(vector_field);
      display_surface();
}

void plot1(int x,int y,int c);
void plot1(int x,int y,int c)
{
      if (x>0 && x<scr_par.width-3 && y>0 && y<scr_par.height-3)
            assign_max(&(surface1)[x+y*scr_par.width],c);
}

void plot2(int x,int y,int c);
void plot2(int x,int y,int c)
{
      int ty;

      if (x>0 && x<scr_par.width-3 && y>0 && y<scr_par.height-3) {
            ty = y*scr_par.width;
            assign_max(&(surface1)[x+ty],c);
            assign_max(&(surface1)[x+1+ty],c);
            assign_max(&(surface1)[x+ty+scr_par.width],c);
            assign_max(&(surface1)[x+1+ty+scr_par.width],c);
      }
}


void plot3(int x,int y,int c);
void plot3(int x,int y,int c)
{
      int ty;

      if (x>0 && x<scr_par.width-3 && y>0 && y<scr_par.height-3) {
            ty = y*scr_par.width;
            assign_max(&(surface1)[x+ty],c/3);
            assign_max(&(surface1)[x+1+ty],c>>1);
            assign_max(&(surface1)[x+ty+scr_par.width],c>>1);
            assign_max(&(surface1)[x+1+ty+scr_par.width],c);
            assign_max(&(surface1)[x+ty+(scr_par.width<<1)],c/3);
            assign_max(&(surface1)[x+2+ty+(scr_par.width<<1)],c/3);
            assign_max(&(surface1)[x+1+ty+(scr_par.width<<1)],c>>1);
            assign_max(&(surface1)[x+2+ty+scr_par.width],c>>1);
            assign_max(&(surface1)[x+2+ty+scr_par.width],c/3);
      }
}

#if 0
void line(int x1,int y1,int x2,int y2,int c)
{
      int i,j;
      float x,y,vx,vy,d;
      const float step=1;

      if (x1==x2 && y1==y2)
            plot3(x1,y1,255);
      else {
            x=x1;
            y=y1;
            d=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
            vx=step*(x2-x1)/d;
            vy=step*(y2-y1)/d;
            for (i=0;i<(int)(d/step)+1;i++) {
                  plot1(x,y,c);
                  x+=vx;
                  y+=vy;
            }
      }
}
#endif

#define SWAP(x,y) \
      x = x + y;  \
      y = x - y;  \
      x = x - y;

void line(int _x1, int _y1, int _x2, int _y2, int _c)
{
      int dx, dy, cxy, dxy;
      /* calculate the distances */
      dx = abs(_x1 - _x2);
      dy = abs(_y1 - _y2);

      cxy = 0;
      if (dy > dx)
      {
            /* Follow Y axis */
            if (_y1 > _y2)
            {
                  SWAP(_y1, _y2);
                  SWAP(_x1, _x2);
            }

            if (_x1 > _x2)
                  dxy = -1;
            else
                  dxy = 1;

            for (_y1=_y1; _y1<_y2; _y1++)
            {
                  cxy += dx;
                  if (cxy >= dy)
                  {
                        _x1+= dxy;
                        cxy -= dy;
                  }
                  plot1(_x1, _y1, _c);
            }
      }
      else
      {
            /* Follow X axis */
            if (_x1 > _x2)
            {
                  SWAP(_x1, _x2);
                  SWAP(_y1, _y2);
            }

            if (_y1 > _y2)
                  dxy = -1;
            else
                  dxy = 1;

            for (_x1=_x1; _x1<_x2; _x1++)
            {
                  cxy += dy;
                  if (cxy >= dx)
                  {
                        _y1+=dxy;
                        cxy -= dx;
                  }
                  plot1(_x1, _y1, _c);
            }
      }
}

struct sincos
{
      int i;
      float *f;
};

/* Little optimization for cos/sin functions */
static struct sincos cosw = { 0, NULL };
static struct sincos sinw = { 0, NULL };

void spectral(t_effect* current_effect,short data[2][512])
{
      int i, halfheight, halfwidth;
      float old_y1,old_y2;
      float _y1=(((data[0][0]+data[1][0])>>9)*current_effect->spectral_amplitude*scr_par.height)>>12;
      float _y2=(((data[0][0]+data[1][0])>>9)*current_effect->spectral_amplitude*scr_par.height)>>12;
      const int density_lines=5;
      const int step=4;
      const int shift=(current_effect->spectral_shift*scr_par.height)>>8;

      if (cosw.i != scr_par.width || sinw.i != scr_par.width)
      {
            free(cosw.f);
            free(sinw.f);
            sinw.f = cosw.f = NULL;
            sinw.i = cosw.i = 0;
      }

      if (cosw.i == 0 || cosw.f == NULL)
      {
            float halfPI  = (float)PI/2;
            cosw.i = scr_par.width;
            cosw.f = malloc(sizeof(float)*scr_par.width);
            for (i=0; i<scr_par.width;i+=step)
                  cosw.f[i] = cos((float)i/scr_par.width*PI+halfPI);
      }

      if (sinw.i == 0 || sinw.f == NULL)
      {
            float halfPI = (float)PI/2;
            sinw.i = scr_par.width;
            sinw.f = malloc(sizeof(float)*scr_par.width);
            for (i=0; i<scr_par.width;i+=step)
                  sinw.f[i] = sin((float)i/scr_par.width*PI+halfPI);
      }

      if (current_effect->mode_spectre==3)
      {
            if (_y1<0)
                  _y1=0;

            if (_y2<0)
                  _y2=0;
      }

      halfheight = scr_par.height >> 1;
      halfwidth  = scr_par.width >> 1;
      for (i=step;i<scr_par.width;i+=step)
      {
            old_y1=_y1;
            old_y2=_y2;
            _y1=((data[1][(i<<9)/scr_par.width/density_lines]>>8)*
                current_effect->spectral_amplitude*scr_par.height)>>12;
            _y2=((data[0][(i<<9)/scr_par.width/density_lines]>>8)*
                current_effect->spectral_amplitude*scr_par.height)>>12;

            switch (current_effect->mode_spectre)
            {
            case 0:
                  line(i-step,halfheight+shift+old_y2,
                       i,halfheight+shift+_y2,
                       current_effect->spectral_color);
                  break;
            case 1:
                  line(i-step,halfheight+shift+old_y1,
                       i,halfheight+shift+_y1,
                       current_effect->spectral_color);
                  line(i-step,halfheight-shift+old_y2,
                       i,halfheight-shift+_y2,
                       current_effect->spectral_color);
                  break;
            case 2:
                  line(i-step,halfheight+shift+old_y1,
                       i,halfheight+shift+_y1,
                       current_effect->spectral_color);
                  line(i-step,halfheight-shift+old_y1,
                       i,halfheight-shift+_y1,
                       current_effect->spectral_color);
                  line(halfwidth+shift+old_y2,i-step,
                       halfwidth+shift+_y2,i,
                       current_effect->spectral_color);
                  line(halfwidth-shift+old_y2,i-step,
                       halfwidth-shift+_y2,i,
                       current_effect->spectral_color);
                  break;
            case 3:
                  if (_y1<0)
                        _y1=0;
                  if (_y2<0)
                        _y2=0;
            case 4:
                  line(halfwidth  + cosw.f[i-step] * (shift+old_y1),
                       halfheight + sinw.f[i-step] * (shift+old_y1),
                       halfwidth  + cosw.f[i]      * (shift+_y1),
                       halfheight + sinw.f[i]      * (shift+_y1),
                       current_effect->spectral_color);
                  line(halfwidth  - cosw.f[i-step] * (shift+old_y2),
                       halfheight + sinw.f[i-step] * (shift+old_y2),
                       halfwidth  - cosw.f[i]      * (shift+_y2),
                       halfheight + sinw.f[i]      * (shift+_y2),
                       current_effect->spectral_color);
                  break;
            }
      }

      if (current_effect->mode_spectre==3 || current_effect->mode_spectre==4)
            line(halfwidth  + cosw.f[scr_par.width - step] * (shift+_y1),
                 halfheight + sinw.f[scr_par.width - step] * (shift+_y1),
                 halfwidth  - cosw.f[scr_par.width - step] * (shift+_y2),
                 halfheight + sinw.f[scr_par.width - step] * (shift+_y2),
                 current_effect->spectral_color);
}

void curve(t_effect* current_effect)
{
      int i,j,k;
      float v,vr;
      float x,y;
      float amplitude=(float)current_effect->curve_amplitude/256;

      for (j=0;j<2;j++)
      {
            v=80;
            vr=0.001;
            k=current_effect->x_curve;
            for (i=0;i<64;i++)
            {
                  x=cos((float)(k)/(v+v*j*1.34))*scr_par.height*amplitude;
                  y=sin((float)(k)/(1.756*(v+v*j*0.93)))*scr_par.height*amplitude;
                  plot2(x*cos((float)k*vr)+y*sin((float)k*vr)+scr_par.width/2,
                        x*sin((float)k*vr)-y*cos((float)k*vr)+scr_par.height/2,
                        current_effect->curve_color);
                  k++;
            }
      }
      current_effect->x_curve=k;
}


void init_sdl(void)
{
      surface1=(byte*)malloc(scr_par.width*scr_par.height);
      surface2=(byte*)malloc(scr_par.width*scr_par.height);

      if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
      {
            fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
            exit(1);
      }

      SDL_WM_SetCaption("Tyler", 0L);
      screen = SDL_SetVideoMode(scr_par.width * scr_par.scale,
            scr_par.height * scr_par.scale, 16, VIDEO_FLAGS);

      if ( screen == NULL )
      {
            fprintf(stderr, "Couldn't init video mode: %s\n", SDL_GetError());
            exit(1);
      }
      SDL_ShowCursor(0);
      SDL_EnableKeyRepeat(0,0);
}

void toggle_fullscreen(void)
{
      SDL_WM_ToggleFullScreen(screen);
}

void close_sdl(void)
{
      SDL_Quit();
}

Generated by  Doxygen 1.6.0   Back to index