Logo Search packages:      
Sourcecode: gtkatlantic version File versions

eng_main.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 "eng_main.h"
#include "eng_conv.h"


/* ---- initialise engine */
void engine_init()  {

#if ENG_DEBUG
      fprintf(stdout, "Initializing engine...\n");
#endif

      engine = g_malloc0( sizeof(_engine) );
}


/* ---- engine init alpha table */
void eng_init_alpha_table()  {

      guint32 alpha, bright;

#if ENG_DEBUG
      fprintf(stdout, "Initializing alpha table...\n");
#endif

      engine->alpha = g_malloc0( sizeof(_alpha) );

      for(alpha = 0 ; alpha < 256 ; alpha++) {

            for(bright = 0 ; bright < 256 ; bright++)  {

                  engine->alpha->fg[alpha][bright] = (bright * alpha) >> 8;
                  engine->alpha->bg[alpha][bright] = (bright * (0xff - alpha)) >> 8;
            }
      }

      engine->table_alpha_is_init = TRUE;
}


/* ---- engine free alpha table */
void eng_free_alpha_table()  {

#if ENG_DEBUG
      fprintf(stdout, "Freeing alpha table...\n");
#endif

      g_free(engine->alpha);
      engine->table_alpha_is_init = FALSE;
}


/* ---- close engine */
void engine_close()  {

      frame_destroy_all();
      if(engine->table_alpha_is_init) eng_free_alpha_table();
      g_free(engine);

#if ENG_DEBUG
      fprintf(stdout, "Closing engine...\n");
#endif
}


/* ---- set minimize memory for engine                          *
 *    You MUST call this function just after initialise engine  *
 *    See eng_main.h for more details about minimize mode       */
void engine_minimize_memory_usage()  {

      if(!engine->lastframe) engine->minimize_memory = TRUE;
}


/* ---- make mask compatible with engine                        *
 *    Use this function ONLY if you use minimize memory mode,   *
 *    call this function for each mask buffer you want to use   *
 *    in engine                                                 *
 *                                                              *
 *    -> size is the size in bytes of input amount of data      *
 *    -> depth can be 8, 16, 24                                 *
 *                                                              *
 *    ++++ IMPORTANT ++++                                       *
 *    This function modify your input buffer, please make sure  *
 *    you don't need original mask                              *
 *                                                              */
void engine_maskcompat(guint32 size, guint16 depth, guchar  * buff)  {

      guint32 nb_pixel, new_size;
      guchar  * tmp;

      if(!buff) return;
      if(!engine->minimize_memory) return;
      if(!size) return;

      switch(depth)  {

            case 8:   nb_pixel = size;      break;      
            case 16:  nb_pixel = size / 2;  break;
            case 24:  nb_pixel = size / 3;  break;
            default:  return;
      }

      new_size = calc_buf_size(nb_pixel, 1, 8);
      tmp = g_malloc0(new_size);

      /* read buff and put converted data in tmp    *
       *    buff -> tmp                             */
      switch(depth)  {

            case 8:   eng_conv_8_to_mask(buff, tmp, nb_pixel);   break;
            case 16:  eng_conv_16_to_mask(buff, tmp, nb_pixel);  break;
            case 24:  eng_conv_24_to_mask(buff, tmp, nb_pixel);  break;
      }

      /* realloc buff and copy tmp to buff   *
       *    tmp -> buff                      */
      buff = g_realloc(buff, new_size);
      memcpy(buff, tmp, new_size);

      g_free(tmp);
}


/* ---- set engine->lastframe */
void set_lastframe()  {

      guint32 i, setval = 0;

      for(i = 1 ; i < MAX_FRAME ; i++)  {

            if(engine->active_frame[i]) setval = i;
      }

      engine->lastframe = setval;
}


/* ---- create a new frame */
guint16 frame_create()  {

      guint32 i;
 
      /* search the first free frame  */
      for(i = 1 ; i < MAX_FRAME ; i++)  {

            if( !engine->active_frame[i] ) {

                  frame[i] = g_malloc0( sizeof(_frame) );
                  frame_reset(i);
                  engine->active_frame[i] = 1;
                  frame[i]->compute = 1;
                  set_lastframe();
#if ENG_DEBUG
                  fprintf(stdout, "New Frame : %d\n", i);
#endif
                  return(i);
                  break;
            }
      }

      /* max number of frames reached ! */
      fprintf(stderr, "ERROR: can't create a new frame\n");

      return(FALSE);
}


/* ---- destroy a frame
 *
 *    close also all pics
 */
void frame_destroy(guint16 frame_id)  {

      guint32 i;

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

      for(i = 1 ; i <= frame[frame_id]->lastpic ; i++)  {

            if(frame[frame_id]->active_pic[i])  pic_destroy(frame_id, i);
      }

      frame_reset(frame_id);
      g_free(frame[frame_id]);
      set_lastframe();

#if ENG_DEBUG
      fprintf(stdout, "Destroy frame : %d\n", frame_id);
#endif
}


/* ---- destroy all frames */
void frame_destroy_all()  {

      guint32 i;

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

            if(engine->active_frame[i])  frame_destroy(i);
      }
}


/* ---- set to 0 all elements in struct */
void frame_reset(guint16 frame_id)  {

      guint32 i;

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

      engine->active_frame[frame_id] = 0;
      frame[frame_id]->compute = 0;
      frame[frame_id]->width = 0;
      frame[frame_id]->height = 0;
      frame[frame_id]->bgcolor[0] = 0;
      frame[frame_id]->bgcolor[1] = 0;
      frame[frame_id]->bgcolor[2] = 0;
      frame[frame_id]->gray_bgcolor = TRUE;
      frame[frame_id]->lastpic = 0;
      frame[frame_id]->lastground = 0;
      if(frame[frame_id]->memalloc > 0)
            g_free(frame[frame_id]->bufout);

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

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

                  frame[frame_id]->zone_upd[i]->x1 = 0;
                  frame[frame_id]->zone_upd[i]->y1 = 0;
                  frame[frame_id]->zone_upd[i]->x2 = 0;
                  frame[frame_id]->zone_upd[i]->y2 = 0;
            }

      frame[frame_id]->nb_zone = 0;
      frame[frame_id]->x_min = 0;
      frame[frame_id]->y_min = 0;
      frame[frame_id]->x_max = 0;
      frame[frame_id]->y_max = 0;
}


/* ---- compute yes this frame (for eng_create_frame_all() ) */
void frame_set_compute(guint16 frame_id) {

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

      frame[frame_id]->compute = 1;
}


/* ---- compute no this frame (for eng_create_frame_all() ) */
void frame_unset_compute(guint16 frame_id)  {

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

      frame[frame_id]->compute = 0;
}


/* ---- clean this frame                              *
 *                                                    *
 *  In the same concept of minimizing memory usage,   *
 *  with this function you can clean all memory       *
 *  used for out buffer, and zone selected buffer.    *
 *                                                    *
 *  Don't use between frame often drawed,             *
 *  because engine do remake all frame, and not       *
 *  just update this, finally engine can become       *
 *  extremely slow.                                   *
 *                                                    *
 *  This is not dependant with minimizing memory mode *
 *                                                    */
void frame_clean(guint16 frame_id)  {

      guint32 i;

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

      if(frame[frame_id]->memalloc > 0)
            g_free(frame[frame_id]->bufout);

      frame[frame_id]->memalloc = 0;

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

      frame[frame_id]->partalloc = 0;

      if(frame[frame_id]->nb_zone > 0)
            for(i = 0 ; i < frame[frame_id]->nb_zone ; i++)  {
                  frame[frame_id]->zone_upd[i]->x1 = 0;
                  frame[frame_id]->zone_upd[i]->y1 = 0;
                  frame[frame_id]->zone_upd[i]->x2 = 0;
                  frame[frame_id]->zone_upd[i]->y2 = 0;
            }

      frame[frame_id]->nb_zone = 0;

      for(i = 1 ; i <= frame[frame_id]->lastpic ; i++ )  {
   
            if(engine->active_frame[i])
                  frame[frame_id]->obj[i]->change = 1;
      }
}


/* ---- set HEIGHT of a frame */
void frame_set_height(guint16 frame_id, guint16 height)  {

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

      frame[frame_id]->height = height;
}


/* ---- set WIDTH of a frame */
void frame_set_width(guint16 frame_id, guint16 width)  {

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

      frame[frame_id]->width = width;
}


/* ---- set BGCOLOR of a frame */
void frame_set_bgcolor(guint16 frame_id, guint32 bgcolor)  {

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

      frame[frame_id]->bgcolor[0] = (bgcolor >> 16) & 0xff; // red
      frame[frame_id]->bgcolor[1] = (bgcolor >> 8) & 0xff;  // green
      frame[frame_id]->bgcolor[2] = bgcolor & 0xff;         // blue

      if(frame[frame_id]->bgcolor[0] == frame[frame_id]->bgcolor[1]  &&  frame[frame_id]->bgcolor[1] == frame[frame_id]->bgcolor[2])
            frame[frame_id]->gray_bgcolor = TRUE;
      else
            frame[frame_id]->gray_bgcolor = FALSE;
}


/* ---- set lastpic of a frame */
void frame_set_lastpic(guint16 frame_id)  {

      guint32 i, setval = 0;

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

      for(i = 1 ; i < MAX_PIC_PER_FRAME ; i++)  {

            if(frame[frame_id]->active_pic[i]) setval = i;
      }

      frame[frame_id]->lastpic = setval;
}


/* ---- set lastground of a frame */
void frame_set_lastground(guint16 frame_id)  {

      guint32 i, setval = 0;

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

      for(i = 1 ; i <= frame[frame_id]->lastpic ; i++)
            if(frame[frame_id]->active_pic[i])
                  if(frame[frame_id]->obj[i]->z  > setval)
                        setval = frame[frame_id]->obj[i]->z;

      frame[frame_id]->lastground = setval;
}


/* ---- return nb_bytes to allocate for a frame */
guint32 frame_size_frame(guint16 frame_id)  {

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

      return(calc_buf_size_24(frame[frame_id]->width, frame[frame_id]->height) );
}


/* ---- put in terminal all arguments of a frame */
void frame_showarg(guint16 frame_id)  {

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

      fprintf(stdout, "====== FRAME ID is %d ======\n", frame_id);
      fprintf(stdout, "  active       -> %d\n", engine->active_frame[frame_id]);
      fprintf(stdout, "  compute      -> %d\n", frame[frame_id]->compute);
      fprintf(stdout, "  width        -> %d\n", frame[frame_id]->width);
      fprintf(stdout, "  height       -> %d\n", frame[frame_id]->height);
      fprintf(stdout, "  bgcolor[R]   -> 0x%.2X\n", frame[frame_id]->bgcolor[0]);
      fprintf(stdout, "  bgcolor[G]   -> 0x%.2X\n", frame[frame_id]->bgcolor[1]);
      fprintf(stdout, "  bgcolor[B]   -> 0x%.2X\n", frame[frame_id]->bgcolor[2]);
      fprintf(stdout, "  ------\n");
      fprintf(stdout, "  gray_bgcolor -> %d\n", frame[frame_id]->gray_bgcolor);
      fprintf(stdout, "  lastpic      -> %d\n", frame[frame_id]->lastpic);
      fprintf(stdout, "  lastground   -> %d\n", frame[frame_id]->lastground);
      fprintf(stdout, "  memalloc     -> %d bytes\n", frame[frame_id]->memalloc);
      fprintf(stdout, "  partalloc    -> %d bytes\n", frame[frame_id]->partalloc);
      fprintf(stdout, "  nb_zone      -> %d\n", frame[frame_id]->nb_zone);
      fprintf(stdout, "  ------\n");
      if(frame_test(frame_id) )
      fprintf(stdout, "  test         -> SUCCESS\n");
      else
      fprintf(stdout, "  test         -> ERROR\n");
      fprintf(stdout, "====================\n");
}


/* ---- test engine arguments */
gboolean frame_test(guint16 frame_id)  {

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

      if(frame[frame_id]->height < 1 || frame[frame_id]->height > MAX_HEIGHT)
            return(FALSE);

      if(frame[frame_id]->width < 1  || frame[frame_id]->width  > MAX_WIDTH)
            return(FALSE);

      return(TRUE);
}


/* ---- create a new pic */
guint16 pic_create(guint16 frame_id)  {

      guint32 i;
 
      if(!engine->active_frame[frame_id]) {

            fprintf(stderr, "ERROR: can't create a new pic because the frame is invalid\n");
            return(FALSE);
      }


      /* search the first free pic  */
      for(i = 1 ; i < MAX_PIC_PER_FRAME ; i++)  {

            if( !frame[frame_id]->active_pic[i] ) {

                  frame[frame_id]->obj[i] = g_malloc0( sizeof(_obj) );
                  pic_reset(frame_id, i);
                  frame[frame_id]->active_pic[i] = 1;
                  frame[frame_id]->obj[i]->show = 1;
                  frame_set_lastpic(frame_id);
#if ENG_DEBUG
                  fprintf(stdout, "Frame : %d, New pic : %d\n", frame_id, i);
#endif
                  return(i);
                  break;
            }
      }

      /* max number of pics reached ! */
      fprintf(stderr, "ERROR: can't create a new pic for frame %d\n", frame_id);

      return(FALSE);
}


/* ---- destroy pic */
void pic_destroy(guint16 frame_id, guint16 pic_id)  {

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

      if(frame[frame_id]->obj[pic_id]->memalloc > 0  &&  !engine->minimize_memory)
            g_free(frame[frame_id]->obj[pic_id]->buf);

      pic_reset(frame_id, pic_id);
      g_free(frame[frame_id]->obj[pic_id]);

      frame_set_lastpic(frame_id);
      frame_set_lastground(frame_id);

#if ENG_DEBUG
      fprintf(stdout, "Frame : %d, Destroy pic : %d\n", frame_id, pic_id);
#endif
}


/* ---- set to 0 all elements in struct */
void pic_reset(guint16 frame_id, guint16 pic_id)  {

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

      frame[frame_id]->active_pic[pic_id] = 0;
      frame[frame_id]->obj[pic_id]->show = 0;
      frame[frame_id]->obj[pic_id]->is_mask = 0;
      frame[frame_id]->obj[pic_id]->is_alphamask = 0;
      frame[frame_id]->obj[pic_id]->x = 0;
      frame[frame_id]->obj[pic_id]->y = 0;
      frame[frame_id]->obj[pic_id]->z = 0;
      frame[frame_id]->obj[pic_id]->width = 0;
      frame[frame_id]->obj[pic_id]->height = 0;
      frame[frame_id]->obj[pic_id]->depth = 0;
      frame[frame_id]->obj[pic_id]->have_transp = 0;
      frame[frame_id]->obj[pic_id]->have_alpha = 0;
      frame[frame_id]->obj[pic_id]->have_mask = 0;
      frame[frame_id]->obj[pic_id]->have_alphamask = 0;
      frame[frame_id]->obj[pic_id]->have_bgcolor = 0;
      frame[frame_id]->obj[pic_id]->transp = 0;
      frame[frame_id]->obj[pic_id]->alpha = 0;
      frame[frame_id]->obj[pic_id]->mask = 0;
      frame[frame_id]->obj[pic_id]->alphamask = 0;
      frame[frame_id]->obj[pic_id]->bgcolor[0] = 0;
      frame[frame_id]->obj[pic_id]->bgcolor[1] = 0;
      frame[frame_id]->obj[pic_id]->bgcolor[2] = 0;
      frame[frame_id]->obj[pic_id]->memalloc = 0;
      frame[frame_id]->obj[pic_id]->buf_fill = 0;
      frame[frame_id]->obj[pic_id]->depth_buf = 0;
      frame[frame_id]->obj[pic_id]->change = 0;
      frame[frame_id]->obj[pic_id]->x_old = 0;
      frame[frame_id]->obj[pic_id]->y_old = 0;
      frame[frame_id]->obj[pic_id]->height_old = 0;
      frame[frame_id]->obj[pic_id]->width_old = 0;
}


/* ---- show this pic */
void pic_show(guint16 frame_id, guint16 pic_id) {

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

      if(!frame[frame_id]->obj[pic_id]->show)  {
   
            frame[frame_id]->obj[pic_id]->show = 1;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- unshow this pic */
void pic_unshow(guint16 frame_id, guint16 pic_id) {

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

      if(frame[frame_id]->obj[pic_id]->show)  {
   
            frame[frame_id]->obj[pic_id]->show = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- mask yes this pic */
void pic_is_mask(guint16 frame_id, guint16 pic_id) {

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

      if(!frame[frame_id]->obj[pic_id]->is_mask)  {
   
            frame[frame_id]->obj[pic_id]->is_mask = 1;
            frame[frame_id]->obj[pic_id]->show = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- mask no this pic */
void pic_isnot_mask(guint16 frame_id, guint16 pic_id) {

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

      if(frame[frame_id]->obj[pic_id]->is_mask)  {
   
            frame[frame_id]->obj[pic_id]->is_mask = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- alpha yes this pic */
void pic_is_alphamask(guint16 frame_id, guint16 pic_id) {

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

      if(!frame[frame_id]->obj[pic_id]->is_alphamask)  {
   
            frame[frame_id]->obj[pic_id]->is_alphamask = 1;
            frame[frame_id]->obj[pic_id]->show = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- alpha no this pic */
void pic_isnot_alphamask(guint16 frame_id, guint16 pic_id) {

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

      if(frame[frame_id]->obj[pic_id]->is_alphamask)  {
   
            frame[frame_id]->obj[pic_id]->is_alphamask = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- set X pos of pic */
void pic_set_x(guint16 frame_id, guint16 pic_id, guint16 x)  {

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

      if(x != frame[frame_id]->obj[pic_id]->x) {

            frame[frame_id]->obj[pic_id]->x = x;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- set Y pos of pic */
void pic_set_y(guint16 frame_id, guint16 pic_id, guint16 y)  {

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

      if(y != frame[frame_id]->obj[pic_id]->y) {

            frame[frame_id]->obj[pic_id]->y = y;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- set Z pos of pic */
void pic_set_z(guint16 frame_id, guint16 pic_id, guint16 z)  {

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

      if(z != frame[frame_id]->obj[pic_id]->z) {

            frame[frame_id]->obj[pic_id]->z = z;
            frame[frame_id]->obj[pic_id]->change = 1;
            frame_set_lastground(frame_id);
      }
}


/* ---- set HEIGHT of pic */
void pic_set_height(guint16 frame_id, guint16 pic_id, guint16 height)  {

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

      if(height != frame[frame_id]->obj[pic_id]->height) {

            frame[frame_id]->obj[pic_id]->height = height;
            frame[frame_id]->obj[pic_id]->change = 1;
       }
}


/* ---- set WIDTH of pic */
void pic_set_width(guint16 frame_id, guint16 pic_id, guint16 width)  {

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

      if(width != frame[frame_id]->obj[pic_id]->width) {

            frame[frame_id]->obj[pic_id]->width = width;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- set DEPTH of pic (only for mask) */
void pic_set_depth(guint16 frame_id, guint16 pic_id, guint16 depth)  {

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

      frame[frame_id]->obj[pic_id]->depth = depth;
}


/* ---- set TRANSP color of pic */
void pic_set_transp(guint16 frame_id, guint16 pic_id, guint32 transp)  {

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

      if( !frame[frame_id]->obj[pic_id]->have_transp  ||  transp !=  frame[frame_id]->obj[pic_id]->transp)  {

            frame[frame_id]->obj[pic_id]->transp = transp;
            frame[frame_id]->obj[pic_id]->have_transp = 1;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- UNset TRANSP color of pic */
void pic_unset_transp(guint16 frame_id, guint16 pic_id)  {

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

      if(frame[frame_id]->obj[pic_id]->have_transp)  {

            frame[frame_id]->obj[pic_id]->transp = 0;
            frame[frame_id]->obj[pic_id]->have_transp = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- set ALPHA value */
void pic_set_alpha(guint16 frame_id, guint16 pic_id, guint8 alpha)  {

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

      if( !frame[frame_id]->obj[pic_id]->have_alpha  ||  alpha !=  frame[frame_id]->obj[pic_id]->alpha)  {

            if(alpha == 0xff)  {  /* 100% opacity */

                  pic_unset_alpha(frame_id, pic_id);
                  return;
            }
            frame[frame_id]->obj[pic_id]->alpha = alpha;
            frame[frame_id]->obj[pic_id]->have_alpha = 1;
            frame[frame_id]->obj[pic_id]->change = 1;

            if(!engine->table_alpha_is_init)  eng_init_alpha_table();
      }
}


/* ---- UNset ALPHA value */
void pic_unset_alpha(guint16 frame_id, guint16 pic_id)  {

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

      if(frame[frame_id]->obj[pic_id]->have_alpha)  {

            frame[frame_id]->obj[pic_id]->alpha = 0;
            frame[frame_id]->obj[pic_id]->have_alpha = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- set MASK of pic */
void pic_set_mask(guint16 frame_id, guint16 pic_id, guint16 mask_id)  {

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

      if( !frame[frame_id]->obj[pic_id]->have_mask  ||  mask_id != frame[frame_id]->obj[pic_id]->mask) {

            frame[frame_id]->obj[pic_id]->mask = mask_id;
            frame[frame_id]->obj[pic_id]->have_mask = 1;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- UNset MASK of pic */
void pic_unset_mask(guint16 frame_id, guint16 pic_id)  {

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

      if(frame[frame_id]->obj[pic_id]->have_mask)  {

            frame[frame_id]->obj[pic_id]->mask = 0;
            frame[frame_id]->obj[pic_id]->have_mask = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- set ALPHAMASK of pic */
void pic_set_alphamask(guint16 frame_id, guint16 pic_id, guint16 alpha_id)  {

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

      if( !frame[frame_id]->obj[pic_id]->have_alphamask  ||  alpha_id != frame[frame_id]->obj[pic_id]->alphamask) {

            frame[frame_id]->obj[pic_id]->alphamask = alpha_id;
            frame[frame_id]->obj[pic_id]->have_alphamask = 1;
            frame[frame_id]->obj[pic_id]->change = 1;

            if(!engine->table_alpha_is_init)  eng_init_alpha_table();
      }
}


/* ---- UNset ALPHAMASK of pic */
void pic_unset_alphamask(guint16 frame_id, guint16 pic_id)  {

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

      if(frame[frame_id]->obj[pic_id]->have_alphamask)  {

            frame[frame_id]->obj[pic_id]->alphamask = 0;
            frame[frame_id]->obj[pic_id]->have_alphamask = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- set BGCOLOR value */
void pic_set_bgcolor(guint16 frame_id, guint16 pic_id, guint32 bgcolor)  {

      guint8 rgb[3];

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

      rgb[0] = (bgcolor >> 16) & 0xff; // red
      rgb[1] = (bgcolor >> 8) & 0xff;  // green
      rgb[2] = bgcolor & 0xff;         // blue

      if( !frame[frame_id]->obj[pic_id]->have_bgcolor  ||  memcmp(&rgb, frame[frame_id]->obj[pic_id]->bgcolor, 3) )  {

            memcpy(frame[frame_id]->obj[pic_id]->bgcolor, &rgb, 3);
            frame[frame_id]->obj[pic_id]->have_bgcolor = 1;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- UNset BGCOLOR value */
void pic_unset_bgcolor(guint16 frame_id, guint16 pic_id)  {

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

      if(frame[frame_id]->obj[pic_id]->have_bgcolor)  {

            frame[frame_id]->obj[pic_id]->bgcolor[0] = 0;
            frame[frame_id]->obj[pic_id]->bgcolor[1] = 0;
            frame[frame_id]->obj[pic_id]->bgcolor[2] = 0;
            frame[frame_id]->obj[pic_id]->have_bgcolor = 0;
            frame[frame_id]->obj[pic_id]->change = 1;
      }
}


/* ---- set/fill BUFFER of pic                * 
 *    call pic_fill_buff() or pic_set_buff()  */
void pic_buff(guint16 frame_id, guint16 pic_id, guchar  * buff)  {

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

      if(engine->minimize_memory)
            pic_set_buff(frame_id, pic_id, buff);
      else
            pic_fill_buff(frame_id, pic_id, buff);
}


/* ---- fill BUFFER of pic             *
 *    copy image buffer under engine   */
void pic_fill_buff(guint16 frame_id, guint16 pic_id, guchar  * buff)  {

      guint32 size = 0, sizechg = 0, chg = 0, nb_pixel;

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

      nb_pixel = frame[frame_id]->obj[pic_id]->width * frame[frame_id]->obj[pic_id]->height;

      /* changed  ? */
      if(frame[frame_id]->obj[pic_id]->is_mask) /* mask /8bits */
            size = calc_buf_size(frame[frame_id]->obj[pic_id]->width, frame[frame_id]->obj[pic_id]->height, 8);

      else if(frame[frame_id]->obj[pic_id]->is_alphamask) /* alpha /8bits */
            size = calc_buf_size(frame[frame_id]->obj[pic_id]->width, frame[frame_id]->obj[pic_id]->height, 8);

      else /* classic rgb /24bits */
            size = calc_buf_size_24(frame[frame_id]->obj[pic_id]->width, frame[frame_id]->obj[pic_id]->height);

      if(size != frame[frame_id]->obj[pic_id]->memalloc)
            sizechg = chg = 1; 

      else if( memcmp(frame[frame_id]->obj[pic_id]->buf, buff, size) != 0)
            chg = 1;

      /* alloc memory */
      if(sizechg)  {

            if(size == 0)  frame[frame_id]->obj[pic_id]->buf = g_malloc(size);
            else frame[frame_id]->obj[pic_id]->buf = g_realloc(frame[frame_id]->obj[pic_id]->buf, size);

            frame[frame_id]->obj[pic_id]->memalloc = size;
      }
 
      /* fill buffer with data */
      if(chg)  {

            if(frame[frame_id]->obj[pic_id]->is_mask) { /* if mask */
      
                  switch(frame[frame_id]->obj[pic_id]->depth)  {

                        case 8:  /* 8bits -> mask */
                              eng_conv_8_to_mask(buff, frame[frame_id]->obj[pic_id]->buf, nb_pixel);
                              frame[frame_id]->obj[pic_id]->depth_buf = 8;
                              break;
            
                        case 16: /* 16bits -> mask */
                              eng_conv_16_to_mask(buff, frame[frame_id]->obj[pic_id]->buf, nb_pixel);
                              frame[frame_id]->obj[pic_id]->depth_buf = 8;
                              break;
            
                        case 24: /* 24 bits -> mask */
                              eng_conv_24_to_mask(buff, frame[frame_id]->obj[pic_id]->buf, nb_pixel);
                              frame[frame_id]->obj[pic_id]->depth_buf = 8;
                              break;
                  }

            }
            else if(frame[frame_id]->obj[pic_id]->is_alphamask)  { /* if alpha */

                  memcpy(frame[frame_id]->obj[pic_id]->buf, buff, frame[frame_id]->obj[pic_id]->memalloc);
                  frame[frame_id]->obj[pic_id]->depth_buf = 8;
            }
            else { /* if classic rgb */

                  memcpy(frame[frame_id]->obj[pic_id]->buf, buff, frame[frame_id]->obj[pic_id]->memalloc);
                  frame[frame_id]->obj[pic_id]->depth_buf = 24;
            }

            frame[frame_id]->obj[pic_id]->buf_fill = 1;
      }

      if(chg) frame[frame_id]->obj[pic_id]->change = 1;
}


/* ---- set BUFFER of pic        *
 *     don't copy image buffer   */
void pic_set_buff(guint16 frame_id, guint16 pic_id, guchar  * buff)  {

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

      frame[frame_id]->obj[pic_id]->buf = buff;

      /* if mask or alphamask */
      if(frame[frame_id]->obj[pic_id]->is_mask  ||  frame[frame_id]->obj[pic_id]->is_alphamask)
            frame[frame_id]->obj[pic_id]->depth_buf = 8;

      /* if classic rgb */
      else  frame[frame_id]->obj[pic_id]->depth_buf = 24;

      frame[frame_id]->obj[pic_id]->change = 1;
}


/* ---- put in terminal all arguments of a pic */
void pic_showarg(guint16 frame_id, guint16 pic_id)  {

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

      fprintf(stdout, "== FRAME ID is %d == PIC ID is %d ==\n", frame_id, pic_id);
      fprintf(stdout, "  active        -> %d\n", frame[frame_id]->active_pic[pic_id]);
      fprintf(stdout, "  show          -> %d\n", frame[frame_id]->obj[pic_id]->show);
      fprintf(stdout, "  is_mask       -> %d\n", frame[frame_id]->obj[pic_id]->is_mask);
      fprintf(stdout, "  is_alphamask  -> %d\n", frame[frame_id]->obj[pic_id]->is_alphamask);
      fprintf(stdout, "  X             -> %d\n", frame[frame_id]->obj[pic_id]->x);
      fprintf(stdout, "  Y             -> %d\n", frame[frame_id]->obj[pic_id]->y);
      fprintf(stdout, "  Z             -> %d\n", frame[frame_id]->obj[pic_id]->z);
      fprintf(stdout, "  width         -> %d\n", frame[frame_id]->obj[pic_id]->width);
      fprintf(stdout, "  height        -> %d\n", frame[frame_id]->obj[pic_id]->height);
      fprintf(stdout, "  depth         -> %d\n", frame[frame_id]->obj[pic_id]->depth);
      fprintf(stdout, "  have_transp   -> %d\n", frame[frame_id]->obj[pic_id]->have_transp);
      fprintf(stdout, "  have_alpha    -> %d\n", frame[frame_id]->obj[pic_id]->have_alpha);
      fprintf(stdout, "  have_mask     -> %d\n", frame[frame_id]->obj[pic_id]->have_mask);
      fprintf(stdout, "  have_alphamask-> %d\n", frame[frame_id]->obj[pic_id]->have_alphamask);
      fprintf(stdout, "  have_bgcolor  -> %d\n", frame[frame_id]->obj[pic_id]->have_bgcolor);
      fprintf(stdout, "  transp        -> 0x%.6X\n", frame[frame_id]->obj[pic_id]->transp);
      fprintf(stdout, "  alpha         -> %d\n", frame[frame_id]->obj[pic_id]->alphamask);
      fprintf(stdout, "  mask          -> %d\n", frame[frame_id]->obj[pic_id]->mask);
      fprintf(stdout, "  alphamask     -> %d\n", frame[frame_id]->obj[pic_id]->alphamask);
      fprintf(stdout, "  bgcolor[R]    -> 0x%.2X\n", frame[frame_id]->obj[pic_id]->bgcolor[0]);
      fprintf(stdout, "  bgcolor[G]    -> 0x%.2X\n", frame[frame_id]->obj[pic_id]->bgcolor[1]);
      fprintf(stdout, "  bgcolor[B]    -> 0x%.2X\n", frame[frame_id]->obj[pic_id]->bgcolor[2]);
      fprintf(stdout, "  ------\n");
      fprintf(stdout, "  memalloc      -> %d bytes\n", frame[frame_id]->obj[pic_id]->memalloc);
      fprintf(stdout, "  buf_fill      -> %d\n", frame[frame_id]->obj[pic_id]->buf_fill);
      fprintf(stdout, "  depth_buf     -> %d\n", frame[frame_id]->obj[pic_id]->depth_buf);
      fprintf(stdout, "  change        -> %d\n", frame[frame_id]->obj[pic_id]->change);
      fprintf(stdout, "  X old         -> %d\n", frame[frame_id]->obj[pic_id]->x_old);
      fprintf(stdout, "  Y old         -> %d\n", frame[frame_id]->obj[pic_id]->y_old);
      fprintf(stdout, "  width old     -> %d\n", frame[frame_id]->obj[pic_id]->width_old);
      fprintf(stdout, "  height old    -> %d\n", frame[frame_id]->obj[pic_id]->height_old);
      fprintf(stdout, "  ------\n");
      if(pic_test(frame_id, pic_id) )
      fprintf(stdout, "  test      -> SUCCESS\n");
      else
      fprintf(stdout, "  test      -> ERROR\n");
      fprintf(stdout, "====================\n");
}


/* ---- test if depth of mask pic_id is good */
gboolean pic_mask_test_depth(guint16 frame_id, guint16 pic_id)  {

      guint16 depth = 0;

      if(!engine->active_frame[frame_id]) return(FALSE);
      if(!frame[frame_id]->active_pic[pic_id]) return(FALSE);

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

      if(depth != 8  &&  depth != 16  &&  depth != 24) return(FALSE);

      return(TRUE);
}


/* ---- test if pic was good */
gboolean pic_test(guint16 frame_id, guint16 pic_id)  {

      guint32 size;
      guint32 mask, alphamask;

      /* --> common */
      if(!engine->active_frame[frame_id]) return(FALSE);
      if(!frame[frame_id]->active_pic[pic_id]) return(FALSE);
      if(!engine->minimize_memory  &&  !frame[frame_id]->obj[pic_id]->buf_fill) return(FALSE);

      /* obj is a mask */
      if(frame[frame_id]->obj[pic_id]->is_mask)  {

            /* test noshow, width, height */
            if(frame[frame_id]->obj[pic_id]->show) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->width  > frame[frame_id]->width ) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->height > frame[frame_id]->height) return(FALSE);
            if(!engine->minimize_memory  &&  !pic_mask_test_depth(frame_id, pic_id) ) return(FALSE);

            /* test no transp/mask/alphamask/alpha/bgcolor set */
            if(frame[frame_id]->obj[pic_id]->have_transp) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->have_mask) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->have_alphamask) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->have_alpha) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->have_bgcolor) return(FALSE);

            /* test if mem alloc is good */
            if(!engine->minimize_memory)  {

                  size = calc_buf_size(frame[frame_id]->obj[pic_id]->width, frame[frame_id]->obj[pic_id]->height, frame[frame_id]->obj[pic_id]->depth_buf);
                  if(frame[frame_id]->obj[pic_id]->memalloc != size) return(FALSE);
            }
      }

      /* obj is an alpha mask */
      else if(frame[frame_id]->obj[pic_id]->is_alphamask)  {

            /* test noshow, x, width, y, height */
            if(frame[frame_id]->obj[pic_id]->show) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->width  > frame[frame_id]->width ) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->height > frame[frame_id]->height) return(FALSE);

            /* test no transp/mask/alpha set */
            if(frame[frame_id]->obj[pic_id]->have_transp) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->have_mask) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->have_alphamask) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->have_alpha) return(FALSE);
            if(frame[frame_id]->obj[pic_id]->have_bgcolor) return(FALSE);

            /* test if mem alloc is good */
            if(!engine->minimize_memory)  {

                  size = calc_buf_size(frame[frame_id]->obj[pic_id]->width, frame[frame_id]->obj[pic_id]->height, 8);
                  if(frame[frame_id]->obj[pic_id]->memalloc != size) return(FALSE);
            }
      }

      /* obj is a pic */
      else  {

            /* test x & width */
            if(frame[frame_id]->obj[pic_id]->x > frame[frame_id]->width - frame[frame_id]->obj[pic_id]->width) return(FALSE);
 
            /* test y & height */
            if(frame[frame_id]->obj[pic_id]->y > frame[frame_id]->height - frame[frame_id]->obj[pic_id]->height) return(FALSE);

            /* test transp */
            if(frame[frame_id]->obj[pic_id]->have_transp)  {

                  if(frame[frame_id]->obj[pic_id]->transp > max_col_val_24() ) return(FALSE);
                  if(frame[frame_id]->obj[pic_id]->have_mask) return(FALSE);
                  if(frame[frame_id]->obj[pic_id]->have_alphamask) return(FALSE);
            }

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

                  if(frame[frame_id]->obj[pic_id]->alpha > max_col_val(8)) return(FALSE);
            }

            /* test if mem alloc is good */
            if(!engine->minimize_memory)  {

                  size = calc_buf_size_24(frame[frame_id]->obj[pic_id]->width, frame[frame_id]->obj[pic_id]->height);
                  if(frame[frame_id]->obj[pic_id]->memalloc != size) return(FALSE);
            }

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

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

                  if( !frame[frame_id]->active_pic[ mask ]) return(FALSE);

                  if( !frame[frame_id]->obj[ mask ]->is_mask ) return(FALSE);

                  if(frame[frame_id]->obj[ mask ]->width  !=  frame[frame_id]->obj[pic_id]->width) return(FALSE);
                  if(frame[frame_id]->obj[ mask ]->height  !=  frame[frame_id]->obj[pic_id]->height) return(FALSE);

                  if(frame[frame_id]->obj[pic_id]->have_alphamask) return(FALSE);
                  if(frame[frame_id]->obj[pic_id]->have_transp) return(FALSE);

                  if( !pic_test(frame_id, mask) ) return(FALSE);
            }

            /* test alpha mask */
            else if(frame[frame_id]->obj[pic_id]->have_alphamask)  {

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

                  if( !frame[frame_id]->active_pic[ alphamask ]) return(FALSE);

                  if( !frame[frame_id]->obj[ alphamask ]->is_alphamask) return(FALSE);

                  if(frame[frame_id]->obj[ alphamask ]->width  !=  frame[frame_id]->obj[pic_id]->width) return(FALSE);
                  if(frame[frame_id]->obj[ alphamask ]->height  !=  frame[frame_id]->obj[pic_id]->height) return(FALSE);

                  if(frame[frame_id]->obj[pic_id]->have_mask) return(FALSE);
                  if(frame[frame_id]->obj[pic_id]->have_transp) return(FALSE);

                  if( !pic_test(frame_id, alphamask) ) return(FALSE);
            }

            /* no test for bgcolor because value can't over 2^24 */
      }

      return(TRUE);
}


/* ---- return max color value */
guint32 max_col_val(guint16 depth)  {

      switch(depth)  {

            case 1:  return(0x1); break;
            case 8:  return(0xFF); break;
            case 16: return(0xFFFF); break;
            case 24: return(0xFFFFFF); break;
            default: return(FALSE); break;
      }

      return(FALSE);
}


/* ---- return max color value
        special for 24 bits mode, because this function
        is often call, just for faster      */
guint32 max_col_val_24()  {

      return(0xFFFFFF);
}


/* ---- return nb of byte to allocate for buf */
guint32 calc_buf_size(guint32 width, guint32 height, guint16 depth)  {

      guint32 tmp;

      if(height <= 0  ||  width <= 0) return(FALSE);

      switch(depth)  {
   
            case 1:
                  tmp = height * width;
                  tmp /= 8;
                  if(tmp % 8 > 0) tmp++;
                  return(tmp);
                  break;
            case 8: return(height * width); break;
            case 16: return(height * width * 2); break;
            case 24: return(height * width * 3); break;
            default: return(FALSE); break;
      }

      return(FALSE);
}


/* ---- return nb of byte to allocate for buf
        special for 24 bits mode, because this function
        is often call, just for faster      */
guint32 calc_buf_size_24(guint32 width, guint32 height)  {

      if(height <= 0  ||  width <= 0) return(FALSE);

      return(height * width * 3);
}



Generated by  Doxygen 1.6.0   Back to index