Logo Search packages:      
Sourcecode: gtkatlantic version File versions

eng_frame.c

/*
 *     gtkatlantic - the gtk+ monopd client, enjoy network monopoly games
 *
 *
 *  Copyright (C) 2002-2004 Rochet Sylvain
 *
 *  gtkatlantic is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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 <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <string.h>

#include "engine.h"


gint obj_valid[MAX_PIC_PER_FRAME], nb_obj_valid;
gint obj_show[MAX_PIC_PER_FRAME], nb_obj_show;
gint obj_modif[MAX_PIC_PER_FRAME], nb_obj_modif;
gint zone_modif[MAX_PIC_PER_FRAME][4], nb_zone_modif;


/* ---- update all frame */
void eng_create_frame_all()  {

      guint32 i;

      for(i = 1 ; i <= engine->lastframe ; i++)  {

            if(engine->active_frame[i] && frame[i]->compute)
                  eng_create_frame(i);
      }
}


/* ---- update a frame */
void eng_create_frame(guint16 frame_id)  {

      gint32 i = 0, j = 0;
      guint32 size = 0;

      if(!engine->active_frame[frame_id]) return;

      frame[frame_id]->x_min = MAX_WIDTH;
      frame[frame_id]->y_min = MAX_HEIGHT;
      frame[frame_id]->x_max = 0;
      frame[frame_id]->y_max = 0;

      /* free zone_upd */
      for(i = 0 ; i < frame[frame_id]->nb_zone ; i++)  {

            g_free( frame[frame_id]->zone_upd[i] );
      }

      /* allocate memory for store out buffer */
      if(!frame[frame_id]->memalloc)  {

            size = calc_buf_size_24(frame[frame_id]->width, frame[frame_id]->height);
            frame[frame_id]->bufout = g_malloc(size);
            eng_set_bg_bufout(frame_id, 0, 0, frame[frame_id]->width -1, frame[frame_id]->height -1);
            frame[frame_id]->memalloc = size;
      }

      /* create table of valid objects */
      for(i = 1, nb_obj_valid = 0 ; i <= frame[frame_id]->lastpic ; i++ )  {
   
            if(!frame[frame_id]->obj[i]->is_mask  &&  !frame[frame_id]->obj[i]->is_alphamask)  {

                  if( pic_test(frame_id, i) )  {
  
                        obj_valid[nb_obj_valid] = i;
                        nb_obj_valid++;
                  }
            }
      }

//    fprintf(stderr, "NB_OBJ_VALID  = %d\n", nb_obj_valid);

      /* create table of showed objects */
      for(i = 0, nb_obj_show = 0 ; i < nb_obj_valid ; i++ )  {
   
            if(frame[frame_id]->obj[ obj_valid[i] ]->show)  {

                  obj_show[nb_obj_show] = obj_valid[i];
                  nb_obj_show++;
            }
      }

//    fprintf(stderr, "NB_OBJ_SHOW   = %d\n", nb_obj_show);

      /* create table of modified objects */
      for(i = 0, nb_obj_modif = 0 ; i < nb_obj_valid ; i++)  {

            if(frame[frame_id]->obj[ obj_valid[i] ]->change) {

                  obj_modif[nb_obj_modif] = obj_valid[i];
                  nb_obj_modif++;
         
                  frame[frame_id]->obj[ obj_valid[i] ]->change = 0;
            }
      }

//    fprintf(stderr, "NB_OBJ_MODIF  = %d\n", nb_obj_modif);


      /* search zones to update */
      for(i = 0, nb_zone_modif = 0 ; i < nb_obj_modif ; i++)  {

            pic_get_zone_old(frame_id, obj_modif[i], &zone_modif[nb_zone_modif][0], &zone_modif[nb_zone_modif][1], &zone_modif[nb_zone_modif][2], &zone_modif[nb_zone_modif][3]);

            if(zone_modif[nb_zone_modif][2] > zone_modif[nb_zone_modif][0]  &&  zone_modif[nb_zone_modif][3] > zone_modif[nb_zone_modif][1])
                  nb_zone_modif++;

            pic_get_zone_new(frame_id, obj_modif[i], &zone_modif[nb_zone_modif][0], &zone_modif[nb_zone_modif][1], &zone_modif[nb_zone_modif][2], &zone_modif[nb_zone_modif][3]);

            if(zone_modif[nb_zone_modif][2] > zone_modif[nb_zone_modif][0]  &&  zone_modif[nb_zone_modif][3] > zone_modif[nb_zone_modif][1])
                  nb_zone_modif++;

            /* store value of x, y, width, height, they are used if image move */
            frame[frame_id]->obj[ obj_modif[i] ]->x_old = frame[frame_id]->obj[ obj_modif[i] ]->x;
            frame[frame_id]->obj[ obj_modif[i] ]->y_old = frame[frame_id]->obj[ obj_modif[i] ]->y;
            frame[frame_id]->obj[ obj_modif[i] ]->width_old = frame[frame_id]->obj[ obj_modif[i] ]->width;
            frame[frame_id]->obj[ obj_modif[i] ]->height_old = frame[frame_id]->obj[ obj_modif[i] ]->height;
   }

/*
      printf("NB_ZONE_MODIF = %d\n", nb_zone_modif);

      for(i = 0 ; i < nb_zone_modif ; i++)  {
            printf("   %d, %d - %d, %d \n", zone_modif[i][0],  zone_modif[i][1], zone_modif[i][2],  zone_modif[i][3] );   
      }
*/

      /* remove redundant zone & superposed zone */
      for(i = 0 ; i < nb_zone_modif ; i++) {
   
            for(j = i +1 ; j < nb_zone_modif ; j++)  {

                  if(   zone_modif[j][0] <= zone_modif[i][2]  \
                    &&  zone_modif[j][2] >= zone_modif[i][0]  \
                    &&  zone_modif[j][1] <= zone_modif[i][3]  \
                    &&  zone_modif[j][3] >= zone_modif[i][1])  {

                        if( zone_modif[j][0] > zone_modif[i][0] )
                              zone_modif[j][0] = zone_modif[i][0];
                        if( zone_modif[j][1] > zone_modif[i][1] )
                              zone_modif[j][1] = zone_modif[i][1];
                        if( zone_modif[j][2] < zone_modif[i][2] )
                              zone_modif[j][2] = zone_modif[i][2];
                        if( zone_modif[j][3] < zone_modif[i][3] )
                              zone_modif[j][3] = zone_modif[i][3];

                        memset(zone_modif[i], 0, 4 * sizeof(gint) );
              
                        break;
                  }
            }
      }

/*
      printf("NB_ZONE_MODIF = %d\n", nb_zone_modif);

      for(i = 0 ; i < nb_zone_modif ; i++)  {
            printf("   %d, %d - %d, %d \n", zone_modif[i][0],  zone_modif[i][1], zone_modif[i][2],  zone_modif[i][3] );   
      }
*/

      /* update bufout, get extrem, fill zone_upd struct  */
      for(i = 0, j = 0 ; i < nb_zone_modif ; i++)  {

            if(zone_modif[i][3] > 0)  { /* consider y2 > 0 if zone exist */
      
                  /* fill zone_upd */
                  frame[frame_id]->zone_upd[j] = g_malloc0( sizeof(_zone_upd) );
                  frame[frame_id]->zone_upd[j]->x1 = zone_modif[i][0];
                  frame[frame_id]->zone_upd[j]->y1 = zone_modif[i][1];
                  frame[frame_id]->zone_upd[j]->x2 = zone_modif[i][2];
                  frame[frame_id]->zone_upd[j]->y2 = zone_modif[i][3];
                  j++;

                  /* extrem */
                  if(zone_modif[i][0] < frame[frame_id]->x_min)
                        frame[frame_id]->x_min = zone_modif[i][0];
                  if(zone_modif[i][1] < frame[frame_id]->y_min)
                        frame[frame_id]->y_min = zone_modif[i][1];
                  if(zone_modif[i][2] > frame[frame_id]->x_max)
                        frame[frame_id]->x_max = zone_modif[i][2];
                  if(zone_modif[i][3] > frame[frame_id]->y_max)
                        frame[frame_id]->y_max = zone_modif[i][3];

                  /* update bufout */
                  eng_update_bufout(frame_id, zone_modif[i][0], zone_modif[i][1], zone_modif[i][2], zone_modif[i][3] );
            }
      }
      frame[frame_id]->nb_zone = j;

      if(!frame[frame_id]->y_max) {
   
            frame[frame_id]->x_min = 0;
            frame[frame_id]->y_min = 0;
            frame[frame_id]->x_max = 0;
            frame[frame_id]->y_max = 0;
      }

/*
      printf("---- nb_zone = %d\n", nb_zone);

      for(i = 0 ; i < nb_zone ; i++)  {

            printf("   %d, %d - %d, %d \n", zone_upd[i]->x1,  zone_upd[i]->y1, zone_upd[i]->x2,  zone_upd[i]->y2 );
      }


      printf("EXTREM: ");
      printf("   %d, %d - %d, %d \n", x_min,  y_min, x_max,  y_max );
*/

}




/* get min/max zone where the pic is displayed before/after change */
void pic_get_zone_update(guint16 frame_id, guint16 pic_id, gint * x1, gint * y1, gint * x2, gint * y2) {

      guint32 x1_old, x1_new, y1_old, y1_new, x2_old, x2_new, y2_old, y2_new;

      /* get new coord */
      x1_new = frame[frame_id]->obj[pic_id]->x;
      y1_new = frame[frame_id]->obj[pic_id]->y;

      x2_new = x1_new + frame[frame_id]->obj[pic_id]->width -1;
      y2_new = y1_new + frame[frame_id]->obj[pic_id]->height -1;

      /* get old coord if exist */
      if(frame[frame_id]->obj[pic_id]->width_old > 0  &&  frame[frame_id]->obj[pic_id]->height_old > 0) {

            x1_old = frame[frame_id]->obj[pic_id]->x_old;
            y1_old = frame[frame_id]->obj[pic_id]->y_old;

            x2_old = x1_old + frame[frame_id]->obj[pic_id]->width_old -1;
            y2_old = y1_old + frame[frame_id]->obj[pic_id]->height_old -1;
      }
      else {
   
            x1_old = x1_new;
            y1_old = y1_new;

            x2_old = x2_new;
            y2_old = y2_new;
      }


      /* search min/max */
      if(x1_new < x1_old)
            *x1 = x1_new;
      else
            *x1 = x1_old;

      if(y1_new < y1_old)
            *y1 = y1_new;
      else
            *y1 = y1_old;

      if(x2_new > x2_old)
            *x2 = x2_new;
      else
            *x2 = x2_old;

      if(y2_new > y2_old)
            *y2 = y2_new;
      else
            *y2 = y2_old;

/*
      printf("\tX1\tY1\tX2\tY2\n");
      printf("new\t%d\t%d\t%d\t%d\n", x1_new, y1_new, x2_new, y2_new);
      printf("old\t%d\t%d\t%d\t%d\n", x1_old, y1_old, x2_old, y2_old);
      printf("fin\t%d\t%d\t%d\t%d\n", *x1, *y1, *x2, *y2);
*/

}




/* get old zone where the pic is displayed before change */
void pic_get_zone_old(guint16 frame_id, guint16 pic_id, gint * x1, gint * y1, gint * x2, gint * y2) {

      *x1 = frame[frame_id]->obj[pic_id]->x_old;
      *y1 = frame[frame_id]->obj[pic_id]->y_old;

      *x2 = *x1 + frame[frame_id]->obj[pic_id]->width_old -1;
      *y2 = *y1 + frame[frame_id]->obj[pic_id]->height_old -1;
}




/* get new zone where the pic is displayed after change */
void pic_get_zone_new(guint16 frame_id, guint16 pic_id, gint * x1, gint * y1, gint * x2, gint * y2) {

      *x1 = frame[frame_id]->obj[pic_id]->x;
      *y1 = frame[frame_id]->obj[pic_id]->y;

      *x2 = *x1 + frame[frame_id]->obj[pic_id]->width -1;
      *y2 = *y1 + frame[frame_id]->obj[pic_id]->height -1;
}



/* update bufout in selected zone */
void eng_update_bufout(guint16 frame_id, guint16 x1, guint16 y1, guint16 x2, guint16 y2)  {

      guint32 i, j, k, l, tmp, pos, mask, alpha_mask, alpha_value, alpha;
      guint   x1_pic, y1_pic, x2_pic, y2_pic;
      guint16 x1_draw, y1_draw, x2_draw, y2_draw;
      guint16 height_draw, width_draw;
      guint32 ptr_memout, ptr_memobj;
      guint16 pic_id;
      guint16 obj_in_zone[MAX_PIC_PER_FRAME], nb_obj_in_zone; 

      eng_set_bg_bufout(frame_id, x1, y1, x2, y2);

      /* search obj in zone to update */
      for(i = 0, nb_obj_in_zone = 0 ; i < nb_obj_show ; i++)  {

            pic_get_zone_new(frame_id, obj_show[i], &x1_pic, &y1_pic, &x2_pic, &y2_pic);
      
            /* obj superposed with zone to update ? */
            if(   x1_pic <= x2
              &&  x2_pic >= x1
              &&  y1_pic <= y2
              &&  y2_pic >= y1)  {
        
                  obj_in_zone[nb_obj_in_zone] = obj_show[i];
                  nb_obj_in_zone++;
            }
      }

/*
      printf(" --- IN ZONE (CHAOS) : %d, %d - %d, %d \n", x1, y1, x2, y2);
      for(i = 0 ; i < nb_obj_in_zone ; i++)  {

            printf("    %3d  -- %3d = %3d, %3d, %3d, %3d\n", obj_in_zone[i], frame[frame_id]->obj[ obj_in_zone[i] ]->z, frame[frame_id]->obj[ obj_in_zone[i] ]->x, frame[frame_id]->obj[ obj_in_zone[i] ]->y, frame[frame_id]->obj[ obj_in_zone[i] ]->x + frame[frame_id]->obj[ obj_in_zone[i] ]->width -1, frame[frame_id]->obj[ obj_in_zone[i] ]->y + frame[frame_id]->obj[ obj_in_zone[i] ]->height -1);
      }
*/

      /* sort table : ground min > max */
      for(i = 0, k = 0 ; i <= frame[frame_id]->lastground ; i++)  {

            for(j = 0 ; j < nb_obj_in_zone ; j++)  {
         
                  if(frame[frame_id]->obj[ obj_in_zone[j] ]->z == i)  {

                        tmp = obj_in_zone[k];
                        obj_in_zone[k] = obj_in_zone[j];
                        obj_in_zone[j] = tmp;
                        k++;
                  }
            }
      }

/*
      printf(" --- IN ZONE (TRIED) : %d, %d - %d, %d \n", x1, y1, x2, y2);
      for(i = 0 ; i < nb_obj_in_zone ; i++)  {
 
            printf("    %3d  -- %3d = %3d, %3d, %3d, %3d\n", obj_in_zone[i], frame[frame_id]->obj[ obj_in_zone[i] ]->z, frame[frame_id]->obj[ obj_in_zone[i] ]->x, frame[frame_id]->obj[ obj_in_zone[i] ]->y, frame[frame_id]->obj[ obj_in_zone[i] ]->x + frame[frame_id]->obj[ obj_in_zone[i] ]->width -1, frame[frame_id]->obj[ obj_in_zone[i] ]->y + frame[frame_id]->obj[ obj_in_zone[i] ]->height -1);
      }
*/

      /* modify bufout */
      for(l = 0 ; l < nb_obj_in_zone ; l++)  {
   
            pic_id = obj_in_zone[l];
            pic_get_zone_new(frame_id, pic_id, &x1_pic, &y1_pic, &x2_pic, &y2_pic);

            /* search part of pic to update */
            if(x1_pic <= x1 ) x1_draw = x1;
            else x1_draw = x1_pic;

            if(y1_pic <= y1 ) y1_draw = y1;
            else y1_draw = y1_pic;

            if(x2_pic >= x2 ) x2_draw = x2;
            else x2_draw = x2_pic;

            if(y2_pic >= y2 ) y2_draw = y2;
            else y2_draw = y2_pic;

/*
            printf(" -> %3d -- %3d, %3d, %3d, %3d\n", pic_id, x1_draw, y1_draw, x2_draw, y2_draw);
*/

            width_draw  = x2_draw - x1_draw +1;
            height_draw = y2_draw - y1_draw +1;

            ptr_memout = y1_draw * frame[frame_id]->width + x1_draw;
            ptr_memobj = (y1_draw - y1_pic) * frame[frame_id]->obj[pic_id]->width + x1_draw - x1_pic;

            /* --->  pic with  alphamask  +  alpha  +  bgcolor */
            if(frame[frame_id]->obj[pic_id]->have_alphamask
                    && frame[frame_id]->obj[pic_id]->have_alpha
                    && frame[frame_id]->obj[pic_id]->have_bgcolor)   {

                  alpha_mask = frame[frame_id]->obj[pic_id]->alphamask;
                  alpha_value = frame[frame_id]->obj[pic_id]->alpha;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              alpha = engine->alpha->fg[ alpha_value ][ frame[frame_id]->obj[ alpha_mask ]->buf[ptr_memobj + j] ];
                              switch(alpha)  {

                                    case 0xff:
                                          memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->buf + pos, 3);
                                          break;

                                    case 0x00:
                                          memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->bgcolor, 3);
                                          break;

                                    default:
                                          for(k = 0 ; k < 3 ; k++) {

                                                *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                  engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                  + engine->alpha->bg[alpha][frame[frame_id]->obj[pic_id]->bgcolor[k]];
                                          }
                                          break;
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }

            }

            /* --->  pic with  alphamask  +  alpha  */
            else if(frame[frame_id]->obj[pic_id]->have_alphamask
                    && frame[frame_id]->obj[pic_id]->have_alpha)   {

                  alpha_mask = frame[frame_id]->obj[pic_id]->alphamask;
                  alpha_value = frame[frame_id]->obj[pic_id]->alpha;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              alpha = engine->alpha->fg[ alpha_value ][ frame[frame_id]->obj[ alpha_mask ]->buf[ptr_memobj + j] ];
                              switch(alpha)  {

                                    case 0xff:
                                          memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->buf + pos, 3);
                                          break;

                                    case 0x00: break;

                                    default:
                                          for(k = 0 ; k < 3 ; k++) {

                                                *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                  engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                  + engine->alpha->bg[alpha][*(frame[frame_id]->bufout + (ptr_memout + j) * 3 + k)];
                                          }
                                          break;
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }

            }

            /* --->  pic with  transparency  +  alpha  +  bgcolor */
            else if(frame[frame_id]->obj[pic_id]->have_transp
              &&  frame[frame_id]->obj[pic_id]->have_alpha
              &&  frame[frame_id]->obj[pic_id]->have_bgcolor)  {
      
                  alpha = frame[frame_id]->obj[pic_id]->alpha;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

//                            if( memcmp(frame[frame_id]->obj[pic_id]->buf + pos, &frame[frame_id]->obj[pic_id]->transp, 3)  )  {

                              if(frame[frame_id]->obj[pic_id]->transp  !=
                                (frame[frame_id]->obj[pic_id]->buf[pos]    << 16)
                                + (frame[frame_id]->obj[pic_id]->buf[pos +1] << 8)
                                + (frame[frame_id]->obj[pic_id]->buf[pos +2])  )  {

                                    switch(alpha)  {

                                          case 0x00:
                                                memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->bgcolor, 3);
                                                break;

                                          default:
                                                for(k = 0 ; k < 3 ; k++) {

                                                      *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                         engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                         + engine->alpha->bg[alpha][frame[frame_id]->obj[pic_id]->bgcolor[k]];
                                                }
                                                break;
                                    }

                              }
                              else {

                                    memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->bgcolor, 3);
                              }

                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }
            }

            /* --->  pic with  transparency  +  alpha  */
            else if(frame[frame_id]->obj[pic_id]->have_transp
                    &&  frame[frame_id]->obj[pic_id]->have_alpha)  {

                  alpha = frame[frame_id]->obj[pic_id]->alpha;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

//                            if( memcmp(frame[frame_id]->obj[pic_id]->buf + pos, &frame[frame_id]->obj[pic_id]->transp, 3)  ) {

                              if(frame[frame_id]->obj[pic_id]->transp  !=
                                (frame[frame_id]->obj[pic_id]->buf[pos]    << 16)
                                + (frame[frame_id]->obj[pic_id]->buf[pos +1] << 8)
                                + (frame[frame_id]->obj[pic_id]->buf[pos +2])  )  {

                                    switch(alpha)  {

                                          case 0x00: break;

                                          default:
                                                for(k = 0 ; k < 3 ; k++) {

                                                      *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                        engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                        + engine->alpha->bg[alpha][*(frame[frame_id]->bufout + (ptr_memout + j) * 3 + k)];
                                                }
                                                break;
                                    }

                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }
            }

            /* --->  pic with  mask  +  alpha  +  bgcolor  */
            else if(frame[frame_id]->obj[pic_id]->have_mask
                    && frame[frame_id]->obj[pic_id]->have_alpha
                    &&  frame[frame_id]->obj[pic_id]->have_bgcolor)  {

                  alpha = frame[frame_id]->obj[pic_id]->alpha;
                  mask = frame[frame_id]->obj[pic_id]->mask;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              if( frame[frame_id]->obj[ mask ]->buf[ptr_memobj + j])  {

                                    switch(alpha)  {

                                          case 0x00:
                                                memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->bgcolor, 3);
                                                break;

                                          default:
                                                for(k = 0 ; k < 3 ; k++) {

                                                      *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                        engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                        + engine->alpha->bg[alpha][frame[frame_id]->obj[pic_id]->bgcolor[k]];
                                                }
                                                break;
                                    }

                              }
                              else {

                                    memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->bgcolor, 3);
                              }

                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }
            }

            /* --->  pic with  mask  +  alpha  */
            else if(frame[frame_id]->obj[pic_id]->have_mask
                   && frame[frame_id]->obj[pic_id]->have_alpha)  {

                  alpha = frame[frame_id]->obj[pic_id]->alpha;
                  mask = frame[frame_id]->obj[pic_id]->mask;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              if( frame[frame_id]->obj[ mask ]->buf[ptr_memobj + j])  {

                                    switch(alpha)  {

                                          case 0x00: break;

                                          default:
                                                for(k = 0 ; k < 3 ; k++) {

                                                      *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                        engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                        + engine->alpha->bg[alpha][*(frame[frame_id]->bufout + (ptr_memout + j) * 3 + k)];
                                                }
                                                break;
                                    }
                              }

                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }
            }

            /* --->  pic with transparency  +  bgcolor */
            else if(frame[frame_id]->obj[pic_id]->have_transp
                   &&  frame[frame_id]->obj[pic_id]->have_bgcolor)  {

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

//                            if( memcmp(frame[frame_id]->obj[pic_id]->buf + pos, &frame[frame_id]->obj[pic_id]->transp, 3)  ) {

                              if(frame[frame_id]->obj[pic_id]->transp  !=
                                (frame[frame_id]->obj[pic_id]->buf[pos]    << 16)
                                + (frame[frame_id]->obj[pic_id]->buf[pos +1] << 8)
                                + (frame[frame_id]->obj[pic_id]->buf[pos +2])  )  {

                                    memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->buf + pos, 3);
                              }
                              else {

                                    memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->bgcolor, 3);
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }
            }

            /* --->  pic with transparency */
            else if(frame[frame_id]->obj[pic_id]->have_transp)  {

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

//                            if( memcmp(frame[frame_id]->obj[pic_id]->buf + pos, &frame[frame_id]->obj[pic_id]->transp, 3)  ) {

                              if(frame[frame_id]->obj[pic_id]->transp  !=
                                (frame[frame_id]->obj[pic_id]->buf[pos]    << 16)
                                + (frame[frame_id]->obj[pic_id]->buf[pos +1] << 8)
                                + (frame[frame_id]->obj[pic_id]->buf[pos +2])  )  {

                                    memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->buf + pos, 3);
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }
            }

            /* --->  pic with mask  +  bgcolor */
            else if(frame[frame_id]->obj[pic_id]->have_mask
                   &&  frame[frame_id]->obj[pic_id]->have_bgcolor)  {

                  mask = frame[frame_id]->obj[pic_id]->mask;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              if( frame[frame_id]->obj[ mask ]->buf[ptr_memobj + j])  {

                                    memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->buf + pos, 3);
                              }
                              else {

                                    memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->bgcolor, 3);
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }

            }

            /* --->  pic with mask */
            else if(frame[frame_id]->obj[pic_id]->have_mask)  {

                  mask = frame[frame_id]->obj[pic_id]->mask;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              if( frame[frame_id]->obj[ mask ]->buf[ptr_memobj + j])  {

                                    memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->buf + pos, 3);
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }

            }

            /* --->  pic with alphamask  +  bgcolor */
            else if(frame[frame_id]->obj[pic_id]->have_alphamask
                   &&  frame[frame_id]->obj[pic_id]->have_bgcolor)  {

                  alpha_mask = frame[frame_id]->obj[pic_id]->alphamask;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              alpha = frame[frame_id]->obj[ alpha_mask ]->buf[ptr_memobj + j];
                              switch(alpha)  {

                                    case 0xff:
                                          memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->buf + pos, 3);
                                          break;

                                    case 0x00:
                                          memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->bgcolor, 3);
                                          break;

                                    default:
                                          for(k = 0 ; k < 3 ; k++) {

                                                *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                  engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                  + engine->alpha->bg[alpha][frame[frame_id]->obj[pic_id]->bgcolor[k]];
                                          }
                                          break;
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }

            }

            /* --->  pic with alphamask */
            else if(frame[frame_id]->obj[pic_id]->have_alphamask)  {

                  alpha_mask = frame[frame_id]->obj[pic_id]->alphamask;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              alpha = frame[frame_id]->obj[ alpha_mask ]->buf[ptr_memobj + j];
                              switch(alpha)  {

                                    case 0xff:
                                          memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->buf + pos, 3);
                                          break;

                                    case 0x00: break;

                                    default:
                                          for(k = 0 ; k < 3 ; k++) {

                                                *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                  engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                  + engine->alpha->bg[alpha][*(frame[frame_id]->bufout + (ptr_memout + j) * 3 + k)];
                                          }
                                          break;
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }

            }

            /* --->  pic with alpha  +  bgcolor */
            else if(frame[frame_id]->obj[pic_id]->have_alpha
                   &&  frame[frame_id]->obj[pic_id]->have_bgcolor)  {

                  alpha = frame[frame_id]->obj[pic_id]->alpha;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              switch(alpha)  {

                                    case 0x00:
                                          memcpy(frame[frame_id]->bufout + (ptr_memout + j) * 3, frame[frame_id]->obj[pic_id]->bgcolor, 3);
                                          break;

                                    default:
                                          for(k = 0 ; k < 3 ; k++) {

                                                *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                  engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                  + engine->alpha->bg[alpha][frame[frame_id]->obj[pic_id]->bgcolor[k]];
                                          }
                                          break;
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }

            }

            /* --->  pic with alpha */
            else if(frame[frame_id]->obj[pic_id]->have_alpha)  {

                  alpha = frame[frame_id]->obj[pic_id]->alpha;

                  for(i = 0 ; i < height_draw ; i ++)  {

                        for(j = 0 ; j < width_draw ; j++)  {

                              pos = (ptr_memobj + j) * 3;

                              switch(alpha)  {

                                    case 0x00: break;

                                    default:
                                          for(k = 0 ; k < 3 ; k++) {

                                                *(frame[frame_id]->bufout + (ptr_memout + j) * 3 +k) =
                                                  engine->alpha->fg[alpha][*(frame[frame_id]->obj[pic_id]->buf + pos +k)]
                                                  + engine->alpha->bg[alpha][*(frame[frame_id]->bufout + (ptr_memout + j) * 3 + k)];
                                          }
                                          break;
                              }
                        }

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }

            }

            /* --->  pic classic rgb */
            else  {

                  for(i = 0 ; i < height_draw ; i ++)  {

                        memcpy(frame[frame_id]->bufout + ptr_memout * 3,
                          frame[frame_id]->obj[pic_id]->buf + ptr_memobj * 3,
                          3 * width_draw);

                        ptr_memout += frame[frame_id]->width;
                        ptr_memobj += frame[frame_id]->obj[pic_id]->width;
                  }
            }

      }

}


void eng_set_bg_bufout(guint16 frame_id, guint16 x1, guint16 y1, guint16 x2, guint16 y2)  {

      guint8 *ptr_memout = frame[frame_id]->bufout + (y1 * frame[frame_id]->width  + x1) * 3;
      guint32 i, j;
      guint32 height = y2 - y1 +1;
      guint32 width = (x2 - x1 +1) * 3;
      guint32 next = frame[frame_id]->width * 3;

      if(frame[frame_id]->gray_bgcolor)
            for(i = 0 ; i < height ; i++, ptr_memout += next)
                  memset(ptr_memout, frame[frame_id]->bgcolor[0], width);

      else
            for(i = 0 ; i < height ; i++, ptr_memout += next)
                  for(j = 0 ; j < width ; j+=3)
                        memcpy(ptr_memout + j, frame[frame_id]->bgcolor, 3);
}


gboolean eng_zone_is_modified(guint16 frame_id, guint16 x1, guint16 y1, guint16 x2, guint16 y2)  {

      guint32 i;

      for(i = 0 ; i < frame[frame_id]->nb_zone ; i++) {

            if(   frame[frame_id]->zone_upd[i]->x1 <= x2
              &&  frame[frame_id]->zone_upd[i]->x2 >= x1
              &&  frame[frame_id]->zone_upd[i]->y1 <= y2
              &&  frame[frame_id]->zone_upd[i]->y2 >= y1)  {
        
                  return(TRUE);
            }
      }

      return(FALSE);
}


gpointer eng_get_zone(guint16 frame_id, guint16 x1, guint16 y1, guint16 x2, guint16 y2)  {

      guint32 i, width, height, real_width, real_height, size;

      width = x2 - x1 +1;
      height = y2 - y1 +1;

      if(x2 >= frame[frame_id]->width) x2 = frame[frame_id]->width -1;
      if(y2 >= frame[frame_id]->height) y2 = frame[frame_id]->height -1;

      real_width = x2 - x1 +1;
      real_height = y2 - y1 +1;

      if(frame[frame_id]->partalloc) g_free(frame[frame_id]->part);   
      frame[frame_id]->partalloc = 0;

      size = calc_buf_size_24(width, height);

      frame[frame_id]->part = g_malloc0(size);

      frame[frame_id]->partalloc = 1;

      for(i = 0 ; i < real_height ; i++) {

            memcpy(frame[frame_id]->part + i * width * 3,
              frame[frame_id]->bufout + ((y1 + i) * frame[frame_id]->width + x1) * 3,
              real_width * 3);
      }

      return(frame[frame_id]->part);
}



gpointer eng_get_next_zone(guint16 frame_id, guint16 * x, guint16 * y, guint16 * width, guint16 * height){

   guint32 i, x1, y1, x2 ,y2;

      for(i = 0 ; i < frame[frame_id]->nb_zone ; i++) {

            if(frame[frame_id]->zone_upd[i]->y2 > 0)  {

                  x1 = frame[frame_id]->zone_upd[i]->x1;
                  y1 = frame[frame_id]->zone_upd[i]->y1;
                  x2 = frame[frame_id]->zone_upd[i]->x2;
                  y2 = frame[frame_id]->zone_upd[i]->y2;
                  frame[frame_id]->zone_upd[i]->y2 = 0;  /* disable this zone */

                  *x = x1;
                  *y = y1;
                  *width = x2 -x1 +1;
                  *height = y2 -y1 +1;

                  return(eng_get_zone(frame_id, x1, y1, x2, y2) );
            }
      }

      return(NULL);
}



Generated by  Doxygen 1.6.0   Back to index