X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_filter%2Fpuzzle.c;h=b50fd49d195b8ed3b0f5b64ef7f152f342793a18;hb=4e57bfa7f0ad081f216f4f99b7a3f84d40c493ca;hp=7113012185f396e8841fae625defd86c28a3ece7;hpb=3147cc20d467e776b8996268e04352729c26a66d;p=vlc diff --git a/modules/video_filter/puzzle.c b/modules/video_filter/puzzle.c index 7113012185..b50fd49d19 100644 --- a/modules/video_filter/puzzle.c +++ b/modules/video_filter/puzzle.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "filter_picture.h" @@ -58,9 +59,9 @@ vlc_module_begin() set_category( CAT_VIDEO ) set_subcategory( SUBCAT_VIDEO_VFILTER ) - add_integer_with_range( CFG_PREFIX "rows", 4, 1, 128, NULL, + add_integer_with_range( CFG_PREFIX "rows", 4, 2, 16, NULL, ROWS_TEXT, ROWS_LONGTEXT, false ) - add_integer_with_range( CFG_PREFIX "cols", 4, 1, 128, NULL, + add_integer_with_range( CFG_PREFIX "cols", 4, 2, 16, NULL, COLS_TEXT, COLS_LONGTEXT, false ) add_bool( CFG_PREFIX "black-slot", false, NULL, BLACKSLOT_TEXT, BLACKSLOT_LONGTEXT, false ) @@ -164,7 +165,7 @@ static int Open( vlc_object_t *p_this ) var_AddCallback( p_filter, CFG_PREFIX "black-slot", PuzzleCallback, p_sys ); p_filter->pf_video_filter = Filter; - p_filter->pf_mouse = Mouse; + p_filter->pf_video_mouse = Mouse; return VLC_SUCCESS; } @@ -218,70 +219,60 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_pic ) const int i_rows = p_sys->i_rows; const int i_cols = p_sys->i_cols; - /* */ + /* Draw each piece of the puzzle at the right place */ for( int i_plane = 0; i_plane < p_outpic->i_planes; i_plane++ ) { const plane_t *p_in = &p_pic->p[i_plane]; - const int i_pitch = p_in->i_pitch; plane_t *p_out = &p_outpic->p[i_plane]; for( int i = 0; i < i_cols * i_rows; i++ ) { - int i_col = i % i_cols; - int i_row = i / i_cols; - int i_ocol = p_sys->pi_order[i] % i_cols; - int i_orow = p_sys->pi_order[i] / i_cols; - int i_last_row = i_row + 1; - i_orow *= p_in->i_lines / i_rows; - i_row *= p_in->i_lines / i_rows; - i_last_row *= p_in->i_lines / i_rows; - - if( p_sys->b_blackslot && p_sys->b_finished && i == p_sys->i_selected ) + int i_piece_height = p_out->i_visible_lines / i_rows; + int i_piece_width = p_out->i_visible_pitch / i_cols; + + int i_col = (i % i_cols) * i_piece_width; + int i_row = (i / i_cols) * i_piece_height; + int i_last_row = i_row + i_piece_height; + + int i_ocol = (p_sys->pi_order[i] % i_cols) * i_piece_width; + int i_orow = (p_sys->pi_order[i] / i_cols) * i_piece_height; + + if( p_sys->b_blackslot && !p_sys->b_finished && i == p_sys->i_selected ) { uint8_t color = ( i_plane == Y_PLANE ? 0x0 : 0x80 ); - for( ; i_row < i_last_row; i_row++, i_orow++ ) + for( int r = i_row; r < i_last_row; r++ ) { - memset( p_out->p_pixels + i_row * i_pitch + i_col * i_pitch / i_cols, - color, i_pitch / i_cols ); + memset( p_out->p_pixels + r * p_out->i_pitch + i_col, + color, i_piece_width ); } } else { - for( ; i_row < i_last_row; i_row++, i_orow++ ) + for( int r = i_row, or = i_orow; r < i_last_row; r++, or++ ) { - memcpy( p_out->p_pixels + i_row * i_pitch + i_col * i_pitch / i_cols, - p_in->p_pixels + i_orow * i_pitch + i_ocol * i_pitch / i_cols, - i_pitch / i_cols ); + memcpy( p_out->p_pixels + r * p_out->i_pitch + i_col, + p_in->p_pixels + or * p_in->i_pitch + i_ocol, + i_piece_width ); } } - } - } - - if( p_sys->i_selected != -1 && !p_sys->b_blackslot ) - { - const plane_t *p_in = &p_pic->p[Y_PLANE]; - const int i_pitch = p_in->i_pitch; - plane_t *p_out = &p_outpic->p[Y_PLANE]; - int i_col = p_sys->i_selected % i_cols; - int i_row = p_sys->i_selected / i_cols; - int i_last_row = i_row + 1; - i_row *= p_in->i_lines / i_rows; - i_last_row *= p_in->i_lines / i_rows; - memset( p_out->p_pixels + i_row * i_pitch + i_col * i_pitch / i_cols, - 0xff, i_pitch / i_cols ); - for( ; i_row < i_last_row; i_row++ ) - { - p_out->p_pixels[ i_row * i_pitch - + i_col * i_pitch / i_cols ] = 0xff; - p_out->p_pixels[ i_row * i_pitch - + (i_col+1) * i_pitch / i_cols - 1 ] = 0xff; + /* Draw the borders of the selected slot */ + if( i_plane == 0 && !p_sys->b_blackslot && p_sys->i_selected == i ) + { + memset( p_out->p_pixels + i_row * p_out->i_pitch + i_col, + 0xff, i_piece_width ); + for( int r = i_row; r < i_last_row; r++ ) + { + p_out->p_pixels[r * p_out->i_pitch + i_col + 0 + 0 ] = 0xff; + p_out->p_pixels[r * p_out->i_pitch + i_col + i_piece_width - 1 ] = 0xff; + } + memset( p_out->p_pixels + (i_last_row - 1) * p_out->i_pitch + i_col, + 0xff, i_piece_width ); + } } - i_row--; - memset( p_out->p_pixels + i_row * i_pitch + i_col * i_pitch / i_cols, - 0xff, i_pitch / i_cols ); } + /* Draw the 'Shuffle' button if the puzzle is finished */ if( p_sys->b_finished ) { plane_t *p_out = &p_outpic->p[Y_PLANE]; @@ -304,6 +295,7 @@ static int Mouse( filter_t *p_filter, vlc_mouse_t *p_mouse, filter_sys_t *p_sys = p_filter->p_sys; const video_format_t *p_fmt = &p_filter->fmt_in.video; + /* Only take events inside the puzzle erea */ if( p_new->i_x < 0 || p_new->i_x >= (int)p_fmt->i_width || p_new->i_y < 0 || p_new->i_y >= (int)p_fmt->i_height ) return VLC_EGENERIC; @@ -311,6 +303,7 @@ static int Mouse( filter_t *p_filter, vlc_mouse_t *p_mouse, /* */ const bool b_clicked = vlc_mouse_HasPressed( p_old, p_new, MOUSE_BUTTON_LEFT ); + /* If the puzzle is finished, shuffle it if needed */ if( p_sys->b_finished ) { if( b_clicked && @@ -347,15 +340,12 @@ static int Mouse( filter_t *p_filter, vlc_mouse_t *p_mouse, || p_sys->i_selected == i_pos + p_sys->i_cols || p_sys->i_selected == i_pos - p_sys->i_cols ) { + /* Swap two pieces */ int a = p_sys->pi_order[ p_sys->i_selected ]; p_sys->pi_order[ p_sys->i_selected ] = p_sys->pi_order[ i_pos ]; p_sys->pi_order[ i_pos ] = a; - if( p_sys->b_blackslot ) - p_sys->i_selected = i_pos; - else - p_sys->i_selected = -1; - + p_sys->i_selected = p_sys->b_blackslot ? i_pos : -1; p_sys->b_finished = IsFinished( p_sys ); } return VLC_EGENERIC; @@ -404,7 +394,7 @@ static bool IsValid( filter_sys_t *p_sys ) { const int i_count = p_sys->i_cols * p_sys->i_rows; - if( p_sys->b_blackslot ) + if( !p_sys->b_blackslot ) return true; int d = 0; @@ -428,29 +418,29 @@ static bool IsValid( filter_sys_t *p_sys ) static void Shuffle( filter_sys_t *p_sys ) { - const int i_count = p_sys->i_cols * p_sys->i_rows; + const unsigned i_count = p_sys->i_cols * p_sys->i_rows; free( p_sys->pi_order ); p_sys->pi_order = calloc( i_count, sizeof(*p_sys->pi_order) ); do { - for( int i = 0; i < i_count; i++ ) + for( unsigned i = 0; i < i_count; i++ ) p_sys->pi_order[i] = -1; - for( int c = 0; c < i_count; ) + for( unsigned c = 0; c < i_count; ) { - int i = rand() % i_count; + unsigned i = ((unsigned)vlc_mrand48()) % i_count; if( p_sys->pi_order[i] == -1 ) p_sys->pi_order[i] = c++; } p_sys->b_finished = IsFinished( p_sys ); - } while( p_sys->b_finished || IsValid( p_sys ) ); + } while( p_sys->b_finished || !IsValid( p_sys ) ); if( p_sys->b_blackslot ) { - for( int i = 0; i < i_count; i++ ) + for( unsigned i = 0; i < i_count; i++ ) { if( p_sys->pi_order[i] == i_count - 1 ) {