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;
}
Beispiel #3
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 = &regions[data->region1] ;

    if ( data->region2 < 0 || data->region2 > 31 )
        scrolls[n].region2 = 0 ;
    else
        scrolls[n].region2 = &regions[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;
}