static int check_collision_box( INSTANCE * proc1, GRAPH * bmp1, REGION * bbox1, INSTANCE * proc2 ) { REGION bbox2 ; GRAPH * bmp2 ; bmp2 = instance_graph( proc2 ) ; if ( !bmp2 ) return 0 ; instance_get_bbox( proc2, bmp2, &bbox2 ); region_union( &bbox2, bbox1 ) ; if ( region_is_empty( &bbox2 ) ) return 0 ; return 1; }
static int check_collision_circle( INSTANCE * proc1, GRAPH * bmp1, REGION * bbox1, INSTANCE * proc2 ) { REGION bbox2 ; GRAPH * bmp2 ; int cx1, cy1, cx2, cy2, dx1, dy1, dx2, dy2; bmp2 = instance_graph( proc2 ) ; if ( !bmp2 ) return 0 ; instance_get_bbox( proc2, bmp2, &bbox2 ); cx1 = bbox1->x + ( dx1 = ( bbox1->x2 - bbox1->x + 1 ) ) / 2 ; cy1 = bbox1->y + ( dy1 = ( bbox1->y2 - bbox1->y + 1 ) ) / 2 ; cx2 = bbox2.x + ( dx2 = ( bbox2.x2 - bbox2.x + 1 ) ) / 2 ; cy2 = bbox2.y + ( dy2 = ( bbox2.y2 - bbox2.y + 1 ) ) / 2 ; if ( get_distance( cx1, cy1, 0, cx2, cy2, 0 ) < ( ( dx1 + dy1 ) / 2 + ( dx2 + dy2 ) / 2 ) / 2 ) return 1; return 0; }
void scroll_update( int n ) { int x0, y0, x1, y1, cx, cy, w, h, speed ; REGION bbox; GRAPH * gr, * graph, * back; SCROLL_EXTRA_DATA * data; if ( n < 0 || n > 9 ) return ; if ( !scrolls[n].active || !scrolls[n].region || !scrolls[n].graphid ) return ; graph = scrolls[n].graphid ? bitmap_get( scrolls[n].fileid, scrolls[n].graphid ) : 0 ; back = scrolls[n].backid ? bitmap_get( scrolls[n].fileid, scrolls[n].backid ) : 0 ; if ( !graph ) return ; // El fondo de scroll no existe if ( scrolls[n].backid && !back ) return ; // Grafico no existe data = &(( SCROLL_EXTRA_DATA * ) &GLODWORD( libscroll, SCROLLS ) )[n] ; w = scrolls[n].region->x2 - scrolls[n].region->x + 1 ; h = scrolls[n].region->y2 - scrolls[n].region->y + 1 ; scrolls[n].z = data->z ; scrolls[n].ratio = data->ratio ; scrolls[n].camera = instance_get( data->camera ) ; scrolls[n].speed = data->speed ; if ( data->follows < 0 || data->follows > 9 ) scrolls[n].follows = 0 ; else scrolls[n].follows = &scrolls[data->follows] ; if ( data->region1 < 0 || data->region1 > 31 ) scrolls[n].region1 = 0 ; else scrolls[n].region1 = ®ions[data->region1] ; if ( data->region2 < 0 || data->region2 > 31 ) scrolls[n].region2 = 0 ; else scrolls[n].region2 = ®ions[data->region2] ; /* Actualiza las variables globales (perseguir la camara, etc) */ if ( scrolls[n].follows ) { if ( scrolls[n].ratio ) { data->x0 = scrolls[n].follows->x0 * 100 / scrolls[n].ratio ; data->y0 = scrolls[n].follows->y0 * 100 / scrolls[n].ratio ; } else { data->x0 = scrolls[n].follows->x0 ; data->y0 = scrolls[n].follows->y0 ; } } if ( scrolls[n].camera ) { /* Mira a ver si entra dentro de la region 1 o 2 */ speed = scrolls[n].speed ; if ( scrolls[n].speed == 0 ) speed = 9999999 ; /* Update speed */ if (( gr = instance_graph( scrolls[n].camera ) ) ) { instance_get_bbox( scrolls[n].camera, gr, &bbox ); x0 = bbox.x - data->x0 ; y0 = bbox.y - data->y0 ; x1 = bbox.x2 - data->x0 ; y1 = bbox.y2 - data->y0 ; if ( scrolls[n].region1 && ( x0 < scrolls[n].region1->x2 && y0 < scrolls[n].region1->y2 && x1 > scrolls[n].region1->x && y1 > scrolls[n].region1->y ) ) { speed = 0 ; } else if ( scrolls[n].region2 ) { if ( x0 > scrolls[n].region2->x2 ) speed = ( x0 - scrolls[n].region2->x2 ); if ( y0 > scrolls[n].region2->y2 ) speed = ( y0 - scrolls[n].region2->y2 ); if ( x1 < scrolls[n].region2->x ) speed = ( scrolls[n].region2->x - x1 ); if ( y1 < scrolls[n].region2->y ) speed = ( scrolls[n].region2->y - y1 ); } } /* Forzar a que esté en el centro de la ventana */ cx = LOCDWORD( libscroll, scrolls[n].camera, COORDX ) ; cy = LOCDWORD( libscroll, scrolls[n].camera, COORDY ) ; RESOLXY( libscroll, scrolls[n].camera, cx, cy ); cx -= w / 2 ; cy -= h / 2 ; if ( data->x0 < cx ) data->x0 = MIN( data->x0 + speed, cx ) ; if ( data->y0 < cy ) data->y0 = MIN( data->y0 + speed, cy ) ; if ( data->x0 > cx ) data->x0 = MAX( data->x0 - speed, cx ) ; if ( data->y0 > cy ) data->y0 = MAX( data->y0 - speed, cy ) ; } /* Scrolls no cíclicos y posición del background */ if ( graph ) { if ( !( scrolls[n].flags & GRAPH_HWRAP ) ) data->x0 = MAX( 0, MIN( data->x0, ( int )graph->width - w ) ) ; if ( !( scrolls[n].flags & GRAPH_VWRAP ) ) data->y0 = MAX( 0, MIN( data->y0, ( int )graph->height - h ) ) ; } if ( scrolls[n].ratio ) { data->x1 = data->x0 * 100 / scrolls[n].ratio ; data->y1 = data->y0 * 100 / scrolls[n].ratio ; } if ( back ) { if ( !( scrolls[n].flags & BACK_HWRAP ) ) data->x1 = MAX( 0, MIN( data->x1, ( int )back->width - w ) ) ; if ( !( scrolls[n].flags & BACK_VWRAP ) ) data->y1 = MAX( 0, MIN( data->y1, ( int )back->height - h ) ) ; } /* Actualiza la posición del scroll según las variables globales */ scrolls[n].posx0 = data->x0 ; scrolls[n].posy0 = data->y0 ; scrolls[n].x0 = data->x0 % ( int32_t ) graph->width ; scrolls[n].y0 = data->y0 % ( int32_t ) graph->height ; if ( scrolls[n].x0 < 0 ) scrolls[n].x0 += graph->width ; if ( scrolls[n].y0 < 0 ) scrolls[n].y0 += graph->height ; if ( back ) { scrolls[n].x1 = data->x1 % ( int32_t ) back->width ; scrolls[n].y1 = data->y1 % ( int32_t ) back->height ; if ( scrolls[n].x1 < 0 ) scrolls[n].x1 += back->width ; if ( scrolls[n].y1 < 0 ) scrolls[n].y1 += back->height ; } }
static int __collision( INSTANCE * my, int id, int colltype ) { INSTANCE * ptr, ** ctx ; int status, p ; int ( *colfunc )( INSTANCE *, GRAPH *, REGION *, INSTANCE * ); REGION bbox1 ; GRAPH * bmp1 ; if ( id == -1 ) return ( check_collision_with_mouse( my, colltype ) ) ? 1 : 0 ; switch ( colltype ) { case COLLISION_NORMAL: colfunc = check_collision; break; case COLLISION_BOX: colfunc = check_collision_box; break; case COLLISION_CIRCLE: colfunc = check_collision_circle; break; default: return 0; } bmp1 = instance_graph( my ) ; if ( !bmp1 ) return 0 ; instance_get_bbox( my, bmp1, &bbox1 ); int ctype = LOCDWORD( mod_grproc, my, CTYPE ); /* Checks only for a single instance */ if ( id >= FIRST_INSTANCE_ID ) return ( ( ( ptr = instance_get( id ) ) && ctype == LOCDWORD( mod_grproc, ptr, CTYPE ) ) ? colfunc( my, bmp1, &bbox1, ptr ) : 0 ) ; /* we must use full list of instances or get types from it */ ptr = first_instance ; if ( !id ) { LOCDWORD( mod_grproc, my, GRPROC_TYPE_SCAN ) = 0 ; if ( ( p = LOCDWORD( mod_grproc, my, GRPROC_ID_SCAN ) ) ) { ptr = instance_get( p ) ; if ( ptr ) ptr = ptr->next ; } while ( ptr ) { if ( ptr != my && ctype == LOCDWORD( mod_grproc, ptr, CTYPE ) && ( ( status = ( LOCDWORD( mod_grproc, ptr, STATUS ) & ~STATUS_WAITING_MASK ) ) == STATUS_RUNNING || status == STATUS_FROZEN ) && colfunc( my, bmp1, &bbox1, ptr ) ) { LOCDWORD( mod_grproc, my, GRPROC_ID_SCAN ) = LOCDWORD( mod_grproc, ptr, PROCESS_ID ) ; return LOCDWORD( mod_grproc, ptr, PROCESS_ID ) ; } ptr = ptr->next ; } return 0 ; } LOCDWORD( mod_grproc, my, GRPROC_ID_SCAN ) = 0 ; /* Check if already in scan by type and we reach limit */ ctx = ( INSTANCE ** ) LOCADDR( mod_grproc, my, GRPROC_CONTEXT ); if ( LOCDWORD( mod_grproc, my, GRPROC_TYPE_SCAN ) != id ) /* Check if type change from last call */ { *ctx = NULL; LOCDWORD( mod_grproc, my, GRPROC_TYPE_SCAN ) = id; } while ( ( ptr = instance_get_by_type( id, ctx ) ) ) { if ( ptr != my && ctype == LOCDWORD( mod_grproc, ptr, CTYPE ) && ( ( status = ( LOCDWORD( mod_grproc, ptr, STATUS ) & ~STATUS_WAITING_MASK ) ) == STATUS_RUNNING || status == STATUS_FROZEN ) && colfunc( my, bmp1, &bbox1, ptr ) ) { return LOCDWORD( mod_grproc, ptr, PROCESS_ID ) ; } } return 0 ; }
static int check_collision( INSTANCE * proc1, GRAPH * bmp1, REGION * bbox3, INSTANCE * proc2 ) { REGION bbox1, bbox2 ; int x, y, w, h ; GRAPH * bmp2 ; bbox1 = *bbox3; bmp2 = instance_graph( proc2 ) ; if ( !bmp2 ) return 0 ; instance_get_bbox( proc2, bmp2, &bbox2 ); region_union( &bbox1, &bbox2 ) ; if ( region_is_empty( &bbox1 ) ) return 0 ; // Solo si las regiones de ambos bbox se superponen w = bbox1.x2 - bbox1.x + 1 ; h = bbox1.y2 - bbox1.y + 1 ; bbox2.x = bbox2.y = 0 ; bbox2.x2 = w - 1 ; bbox2.y2 = h - 1 ; bmp1 = bitmap_new( 0, w, h, sys_pixel_format->depth ) ; if ( !bmp1 ) return 0; bmp2 = bitmap_new( 0, w, h, sys_pixel_format->depth ) ; if ( !bmp2 ) { bitmap_destroy( bmp1 ) ; return 0; } memset( bmp1->data, 0, bmp1->pitch * h ) ; memset( bmp2->data, 0, bmp2->pitch * h ) ; x = LOCINT32( mod_grproc, proc1, COORDX ) ; y = LOCINT32( mod_grproc, proc1, COORDY ) ; RESOLXY( mod_grproc, proc1, x, y ); x -= bbox1.x ; y -= bbox1.y ; draw_at( bmp1, x, y, &bbox2, proc1 ) ; x = LOCINT32( mod_grproc, proc2, COORDX ) ; y = LOCINT32( mod_grproc, proc2, COORDY ) ; RESOLXY( mod_grproc, proc2, x, y ); x -= bbox1.x ; y -= bbox1.y ; draw_at( bmp2, x, y, &bbox2, proc2 ) ; if ( sys_pixel_format->depth == 32 ) { uint32_t * ptr1 = ( uint32_t * ) bmp1->data ; uint32_t * ptr2 = ( uint32_t * ) bmp2->data ; uint8_t * _ptr1 = ( uint8_t * ) ptr1 ; uint8_t * _ptr2 = ( uint8_t * ) ptr2 ; for ( y = 0 ; y < h ; y++ ) { for ( x = 0 ; x < w ; x++, ptr1++, ptr2++ ) { if ( *ptr1 && *ptr2 ) { bitmap_destroy( bmp1 ) ; bitmap_destroy( bmp2 ) ; return 1; } } ptr1 = ( uint32_t * )( _ptr1 += bmp1->pitch ); ptr2 = ( uint32_t * )( _ptr2 += bmp2->pitch ); } } else { if ( sys_pixel_format->depth == 16 ) { uint16_t * ptr1 = ( uint16_t * ) bmp1->data ; uint16_t * ptr2 = ( uint16_t * ) bmp2->data ; uint8_t * _ptr1 = ( uint8_t * ) ptr1 ; uint8_t * _ptr2 = ( uint8_t * ) ptr2 ; for ( y = 0 ; y < h ; y++ ) { for ( x = 0 ; x < w ; x++, ptr1++, ptr2++ ) { if ( *ptr1 && *ptr2 ) { bitmap_destroy( bmp1 ) ; bitmap_destroy( bmp2 ) ; return 1; } } ptr1 = ( uint16_t * )( _ptr1 += bmp1->pitch ); ptr2 = ( uint16_t * )( _ptr2 += bmp2->pitch ); } } else { uint8_t * ptr1 = ( uint8_t * )bmp1->data ; uint8_t * ptr2 = ( uint8_t * )bmp2->data ; uint8_t * _ptr1 = ptr1 ; uint8_t * _ptr2 = ptr2 ; for ( y = 0 ; y < h ; y++ ) { for ( x = 0 ; x < w ; x++, ptr1++, ptr2++ ) { if ( *ptr1 && *ptr2 ) { bitmap_destroy( bmp1 ) ; bitmap_destroy( bmp2 ) ; return 1; } } ptr1 = _ptr1 += bmp1->pitch; ptr2 = _ptr2 += bmp2->pitch; } } } bitmap_destroy( bmp1 ) ; bitmap_destroy( bmp2 ) ; return 0; }
int draw_instance_info( INSTANCE * i, REGION * region, int * z, int * drawme ) { GRAPH * graph; * drawme = 0; LOCDWORD( librender, i, GRAPHPTR ) = ( int )( graph = instance_graph( i ) ); if ( !graph ) { /* region->x = -2; region->y = -2; region->x2 = -2; region->y2 = -2; */ return 0; } int changed; int status; int coordz, coordx, coordy; status = ( LOCDWORD( librender, i, STATUS ) & ~STATUS_WAITING_MASK ) ; coordz = LOCINT32( librender, i, COORDZ ); /* Si tiene grafico o xgraph o (ctype == 0 y esta corriendo o congelado) */ if ( LOCDWORD( librender, i, CTYPE ) == C_SCREEN && ( status == STATUS_RUNNING || status == STATUS_FROZEN ) ) * drawme = 1; coordx = LOCINT32( librender, i, COORDX ); coordy = LOCINT32( librender, i, COORDY ); RESOLXY( librender, i, coordx, coordy ); changed = graph->modified || LOCINT32( librender, i, SAVED_COORDX ) != coordx || LOCINT32( librender, i, SAVED_COORDY ) != coordy || LOCINT32( librender, i, SAVED_COORDZ ) != coordz || LOCDWORD( librender, i, SAVED_GRAPHID ) != LOCDWORD( librender, i, GRAPHID ) || LOCINT32( librender, i, SAVED_ANGLE ) != LOCINT32( librender, i, ANGLE ) || LOCDWORD( librender, i, SAVED_ALPHA ) != LOCDWORD( librender, i, ALPHA ) || LOCDWORD( librender, i, SAVED_BLENDOP ) != LOCDWORD( librender, i, BLENDOP ) || LOCINT32( librender, i, SAVED_GRAPHSIZE ) != LOCINT32( librender, i, GRAPHSIZE ) || LOCINT32( librender, i, SAVED_GRAPHSIZEX ) != LOCINT32( librender, i, GRAPHSIZEX ) || LOCINT32( librender, i, SAVED_GRAPHSIZEY ) != LOCINT32( librender, i, GRAPHSIZEY ) || LOCDWORD( librender, i, SAVED_FLAGS ) != LOCDWORD( librender, i, FLAGS ) || LOCDWORD( librender, i, SAVED_FILEID ) != LOCDWORD( librender, i, FILEID ) || LOCDWORD( librender, i, SAVED_XGRAPH ) != LOCDWORD( librender, i, XGRAPH ) || ( graph->ncpoints && ( LOCDWORD( librender, i, SAVED_CENTERX ) != graph->cpoints[0].x || LOCDWORD( librender, i, SAVED_CENTERY ) != graph->cpoints[0].y ) ) ; if ( changed ) { /* Update key */ * z = coordz; LOCINT32( librender, i, SAVED_COORDX ) = coordx; LOCINT32( librender, i, SAVED_COORDY ) = coordy; LOCINT32( librender, i, SAVED_COORDZ ) = coordz; LOCDWORD( librender, i, SAVED_GRAPHID ) = LOCDWORD( librender, i, GRAPHID ); LOCINT32( librender, i, SAVED_ANGLE ) = LOCINT32( librender, i, ANGLE ); LOCDWORD( librender, i, SAVED_ALPHA ) = LOCDWORD( librender, i, ALPHA ); LOCDWORD( librender, i, SAVED_BLENDOP ) = LOCDWORD( librender, i, BLENDOP ); LOCINT32( librender, i, SAVED_GRAPHSIZE ) = LOCINT32( librender, i, GRAPHSIZE ); LOCINT32( librender, i, SAVED_GRAPHSIZEX ) = LOCINT32( librender, i, GRAPHSIZEX ); LOCINT32( librender, i, SAVED_GRAPHSIZEY ) = LOCINT32( librender, i, GRAPHSIZEY ); LOCDWORD( librender, i, SAVED_FLAGS ) = LOCDWORD( librender, i, FLAGS ); LOCDWORD( librender, i, SAVED_FILEID ) = LOCDWORD( librender, i, FILEID ); LOCDWORD( librender, i, SAVED_XGRAPH ) = LOCDWORD( librender, i, XGRAPH ); if ( graph->ncpoints ) { LOCDWORD( librender, i, SAVED_CENTERX ) = graph->cpoints[0].x; LOCDWORD( librender, i, SAVED_CENTERY ) = graph->cpoints[0].y; } else { LOCDWORD( librender, i, SAVED_CENTERX ) = CPOINT_UNDEFINED; LOCDWORD( librender, i, SAVED_CENTERY ) = CPOINT_UNDEFINED; } instance_get_bbox( i, graph, region ); return 1; } return changed; }