/* * 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 #include #include #include #include #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); }