/***************************************************************************** * puzzle_auto_solve: solve the puzzle depending on auto_solve_speed parameter * = move one piece at the final location each time * auto_solve_countdown is < 0 *****************************************************************************/ void puzzle_auto_solve( filter_t *p_filter) { filter_sys_t *p_sys = p_filter->p_sys; if ( p_sys->s_current_param.i_auto_solve_speed < 500 ) return; if ( --p_sys->i_auto_solve_countdown_val > 0 ) return; /* delay reached, preset next delay and proceed with puzzle_auto_solve */ p_sys->i_auto_solve_countdown_val = init_countdown(p_sys->s_current_param.i_auto_solve_speed); /* random piece to be moved */ int32_t i_start = ((unsigned)vlc_mrand48()) % p_sys->s_allocated.i_pieces_nbr; /* here the computer will help player by placing the piece at the final location */ for (uint32_t i_l = 0; i_l < p_sys->s_allocated.i_pieces_nbr; i_l++) { int32_t i = ( i_l + i_start ) % p_sys->s_allocated.i_pieces_nbr; if ( !p_sys->ps_pieces[i].b_finished ) { for (uint32_t j = 0; j < p_sys->s_allocated.i_pieces_nbr; j++) { if ( p_sys->ps_pieces[j].i_group_ID == p_sys->ps_pieces[i].i_group_ID ) { p_sys->ps_pieces[j].i_actual_angle = 0; p_sys->ps_pieces[j].i_actual_mirror = +1; p_sys->ps_pieces[j].ps_piece_in_plane[0].i_actual_x = p_sys->ps_pieces[j].ps_piece_in_plane[0].i_original_x; p_sys->ps_pieces[j].ps_piece_in_plane[0].i_actual_y = p_sys->ps_pieces[j].ps_piece_in_plane[0].i_original_y; puzzle_calculate_corners( p_filter, j ); } } break; } } }
void puzzle_random_rotate( filter_t *p_filter) { filter_sys_t *p_sys = p_filter->p_sys; /* add random rotation to each piece */ for (uint32_t i = 0; i < p_sys->s_allocated.i_pieces_nbr; i++) { p_sys->ps_pieces[i].i_actual_angle = 0; p_sys->ps_pieces[i].i_actual_mirror = +1; switch ( p_sys->s_current_param.i_rotate ) { case 1: puzzle_rotate_pce( p_filter, i, (( (unsigned) vlc_mrand48()) % ( 2 ) ) * 2, p_sys->ps_pieces[i].i_center_x, p_sys->ps_pieces[i].i_center_y, false ); break; case 2: puzzle_rotate_pce( p_filter, i, (( (unsigned) vlc_mrand48()) % ( 4 ) ), p_sys->ps_pieces[i].i_center_x, p_sys->ps_pieces[i].i_center_y, false ); break; case 3: puzzle_rotate_pce( p_filter, i, (( (unsigned) vlc_mrand48()) % ( 8 ) ), p_sys->ps_pieces[i].i_center_x, p_sys->ps_pieces[i].i_center_y, false ); break; } puzzle_calculate_corners( p_filter, i ); } }
int puzzle_generate_rand_pce_list( filter_t *p_filter, int32_t **pi_pce_lst ) { filter_sys_t *p_sys = p_filter->p_sys; int32_t i_pieces_nbr = p_sys->s_allocated.i_pieces_nbr; if (pi_pce_lst != NULL ) free( *pi_pce_lst ); *pi_pce_lst = (int32_t *)calloc( i_pieces_nbr, sizeof(**pi_pce_lst) ); // sunqueen modify if( !*pi_pce_lst ) return VLC_ENOMEM; for( int32_t i = 0; i < i_pieces_nbr; i++ ) (*pi_pce_lst)[i] = NO_PCE; for( int32_t c = 0; c < i_pieces_nbr; ) { int32_t i = ((unsigned)vlc_mrand48()) % i_pieces_nbr; if( (*pi_pce_lst)[i] == NO_PCE ) (*pi_pce_lst)[i] = c++; } return VLC_SUCCESS; }
static void Shuffle( filter_sys_t *p_sys ) { 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( unsigned i = 0; i < i_count; i++ ) p_sys->pi_order[i] = -1; for( unsigned c = 0; c < 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 ) ); if( p_sys->b_blackslot ) { for( unsigned i = 0; i < i_count; i++ ) { if( p_sys->pi_order[i] == i_count - 1 ) { p_sys->i_selected = i; break; } } } else { p_sys->i_selected = -1; } }
/** * Sort an array of items recursively * @param i_items: number of items * @param pp_items: the array of items * @param p_sortfn: the sorting function * @return nothing */ static inline void playlist_ItemArraySort( unsigned i_items, playlist_item_t **pp_items, sortfn_t p_sortfn ) { if( p_sortfn ) { qsort( pp_items, i_items, sizeof( pp_items[0] ), p_sortfn ); } else /* Randomise */ { unsigned i_position; unsigned i_new; playlist_item_t *p_temp; for( i_position = i_items - 1; i_position > 0; i_position-- ) { i_new = ((unsigned)vlc_mrand48()) % (i_position+1); p_temp = pp_items[i_position]; pp_items[i_position] = pp_items[i_new]; pp_items[i_new] = p_temp; } } }
/***************************************************************************** * generate random bezier data *****************************************************************************/ point_t *puzzle_rand_bezier(uint8_t i_pts_nbr) { #define NB_PRIM 13 /***************************************************************************** * The table below contains bezier points that creates a typical * jigsaw puzzle piece shape. One set has been defined manually. * Then random modifications have been applied. * The best results have been selected and are included here. *****************************************************************************/ const point_t ps_pt[NB_PRIM][19] = { {{ -1, 0}, { -0.708333333333333, 0}, { -0.375, -0.333333333333333}, { -0.166666666666667, 0.0833333333333333}, { -0.0833333333333334, 0.208333333333333}, { -0.375, 0.416666666666667}, { -0.4, 0.583333333333333}, { -0.416666666666667, 0.833333333333333}, { -0.25, 1}, { 0, 1}, { 0.25, 1}, { 0.416666666666667, 0.833333333333333}, { 0.4, 0.583333333333333}, { 0.375, 0.416666666666667}, { 0.0833333333333334, 0.208333333333333}, { 0.166666666666667, 0.0833333333333333}, { 0.375, -0.333333333333333}, { 0.708333333333333, 0}, { 1, 0}}, {{ -1, 0}, { -0.708231074018077, 0.00464090724581488}, { -0.323236452068492, -0.372786060362316}, { -0.116455168200171, 0.044302770499351}, { -0.0335691043909019, 0.211488362938889}, { -0.437927544463254, 0.38719460194857}, { -0.465325829944998, 0.551293871552922}, { -0.483454564038933, 0.65987409733561}, { -0.190232837055291, 0.93567381392124}, { 0.0642797691187335, 0.936855546259066}, {0.313367868665637, 0.938012091966671}, {0.487146524283283, 0.816195130161918}, {0.469545566313243, 0.564387421486367}, {0.446892478470506, 0.24030153060388}, {0.207135456718658, 0.246041323358689}, {0.287851875888374, 0.122157561245575}, {0.492785457693622, -0.19237501290106}, { 0.707786879710212, 0.000871347032899226}, {1, 0}}, {{ -1, 0}, { -0.704537606957651, 0.00470344095405053}, { -0.435930692234854, -0.352359270526667}, { -0.228149843936683, 0.0679948519756222}, { -0.146863413857337, 0.232442568245956}, { -0.400774053301818, 0.353459760810654}, { -0.422294600163745, 0.522585095895632}, { -0.436816721748459, 0.636711316521778}, { -0.139151386987432, 1.08020929564109}, { 0.110882572064929, 1.08261729027387}, {0.36153850539327, 1.08503127493587}, {0.34588115345217, 0.865990116291394}, {0.329903557511847, 0.612892723601664}, {0.308148644342904, 0.26827818823501}, {0.127493141873546, 0.13002329074962}, {0.214157995034913, 0.0010516930680228}, {0.419298604696494, -0.304231373969182}, { 0.710915592189813, -0.00442574861414977}, {1, 0}}, {{ -1, 0}, { -0.712310641244798, -0.00176730760415818}, { -0.493540738434648, -0.309260977632173}, { -0.285884861158849, 0.102814242456153}, { -0.204387117876255, 0.264539501285563}, { -0.420693738052021, 0.397849004532357}, { -0.441431505287778, 0.562611714939519}, { -0.461628378308195, 0.723076990818189}, { -0.237390284827422, 0.937205665156549}, { 0.012635296180645, 0.941029970697368}, {0.262998571390198, 0.94485944149288}, {0.388416614305901, 0.85661645417048}, {0.371248440058972, 0.611257540385605}, {0.345208629600827, 0.239109662732447}, {0.0581354739284663, 0.176880217503811}, {0.136998743377185, 0.0517079719473858}, {0.348267592311711, -0.283619188873049}, { 0.708090161530147, 0.000345266964160967}, {1, 0}}, {{ -1, 0}, { -0.711243094744545, -0.00459592941542872}, { -0.344045254972826, -0.249350550360079}, { -0.133712969208732, 0.170729185550043}, { -0.0464161071620253, 0.345080177938788}, { -0.422103631801675, 0.334575981154338}, { -0.450380528566562, 0.498555760394576}, { -0.467099640727027, 0.595511106801977}, { -0.207078052226595, 0.975846125373965}, { 0.042159574981007, 0.973462055639965}, {0.287191021206139, 0.971118219914322}, {0.330852515542335, 0.808592956913444}, {0.310390322812144, 0.55585802623889}, {0.283433878730578, 0.222910569628582}, {0.164262943948071, 0.173598366742734}, {0.251741291720702, 0.049453960261478}, {0.457341230249114, -0.24232203906962}, { 0.708383662881845, 0.00453591968074395}, {1, 0}}, {{ -1, 0}, { -0.709563566764519, 0.000504612933340335}, { -0.401784990268149, -0.401999124062464}, { -0.193592021826356, 0.0146187796927396}, { -0.111906932669809, 0.178079970851903}, { -0.31875772800715, 0.350308507939804}, { -0.348317101378293, 0.519642874263023}, { -0.364751907373417, 0.613791604139223}, { -0.261109769059908, 0.917602975781519}, { -0.0140971269841824, 0.920487199482641}, {0.239116574515885, 0.923443829366756}, {0.464370661288271, 0.826483978760365}, {0.447638420230199, 0.579781906213412}, {0.422345781938457, 0.206864359478527}, {0.125463036793575, 0.196073913812856}, {0.210079852894537, 0.0665488867084866}, {0.418467910269307, -0.25243580242811}, { 0.703900021885974, 0.00330911444674605}, {1, 0}}, {{ -1, 0}, { -0.705550924110721, 0.00312677407583926}, { -0.415041079490389, -0.256262603613135}, { -0.206251758814373, 0.165228519752475}, { -0.127460686840124, 0.324287121648782}, { -0.353486555975517, 0.448219649272319}, { -0.374301593332884, 0.615673871700604}, { -0.394013085772568, 0.774250221227079}, { -0.28341474824943, 1.03226208905838}, { -0.0332682368974526, 1.03258310507818}, {0.21500235815775, 1.03290171371209}, {0.359673321091526, 0.870921326239785}, {0.339932613238046, 0.624982013252291}, {0.312186121753393, 0.279302764858672}, {0.115889225615101, 0.23413749518865}, {0.199563649684811, 0.112671061164123}, {0.404949947429742, -0.185479078044395}, { 0.711077310890697, -0.00496397607736578}, {1, 0}}, {{ -1, 0}, { -0.703393023950601, 0.00477096251262726}, { -0.397655885794691, -0.396549402674607}, { -0.188941722741602, 0.0154382717692692}, { -0.108388702754651, 0.174444497740687}, { -0.373390092271521, 0.482883861046198}, { -0.40085845720332, 0.649893787354158}, { -0.415216707820891, 0.73719313638733}, { -0.207371750103189, 0.945376369116883}, { 0.0450859051405016, 0.945770549381538}, {0.295681992651987, 0.946161823046823}, {0.436428045351514, 0.895032817250379}, {0.416214840162102, 0.640148265397975}, {0.392784984133714, 0.344702377534045}, {0.112552686103251, 0.228040049100136}, {0.197835182813393, 0.100734153702732}, {0.405083123585628, -0.208636299638369}, { 0.710532321943806, 0.00118461271792703}, {1, 0}}, {{ -1, 0}, { -0.708545258498605, -0.00125649641636185}, { -0.337498620726249, -0.244893936731276}, { -0.124910631945282, 0.17201407250253}, { -0.0378099534640198, 0.342827911406433}, { -0.388593443990334, 0.484174318751186}, { -0.418161094500799, 0.649198946145559}, { -0.437373248647437, 0.756426897124284}, { -0.189109020838902, 0.919750563663455}, { 0.0617320119458061, 0.92141119323056}, {0.31608889374516, 0.923095098586168}, {0.498311890876136, 0.848907293614162}, {0.486010157001842, 0.596632149071449}, {0.461260133020122, 0.0890763897591911}, {0.075676233826577, 0.15314863012444}, {0.155893607369245, 0.0261168678327565}, {0.366248653274704, -0.307000149194794}, { 0.711164480468843, 0.00394203362859574}, {1, 0}}, {{ -1, 0}, { -0.707183721193905, 0.00108263364450203}, { -0.483784802307194, -0.278675576139177}, { -0.276928949597787, 0.142419327760986}, { -0.193170452053892, 0.312925871385917}, { -0.451215340488792, 0.477259970702323}, { -0.47460300367851, 0.643765731024187}, { -0.494031809431451, 0.782086864170215}, { -0.236790915210626, 0.959374429536679}, { 0.0132927154237516, 0.955639549881874}, {0.267150847268955, 0.951848299853113}, {0.394360682972295, 0.847565361471232}, {0.378470732344786, 0.601630247482969}, {0.354536849929646, 0.231195987620713}, {0.0517827835992971, 0.214030018332778}, {0.131796334571256, 0.0912722226051247}, {0.336621017220957, -0.222972380306016}, { 0.703679022364791, -0.00331356185794636}, {1, 0}}, {{ -1, 0}, { -0.71248840208346, -0.000315316402810925}, { -0.335615004340797, -0.24819255482402}, { -0.131187942697538, 0.164054053482729}, { -0.0493962500017139, 0.3289947791894}, { -0.419381248020232, 0.390159881019368}, { -0.441651048160997, 0.558451191050566}, { -0.455822752006908, 0.665545758156122}, { -0.233491027161151, 0.962685238392525}, { 0.0133445688612305, 0.95860585518251}, {0.262151404887793, 0.954493893837471}, {0.353774477399895, 0.909561597589476}, {0.33709535778317, 0.660905314411181}, {0.31704981166686, 0.362061544110332}, {0.105412252277536, 0.191206346512902}, {0.186218651070473, 0.0649153599195794}, {0.398293919310497, -0.266533575537957}, { 0.704071013216639, 0.00309631694609307}, {1, 0}}, {{ -1, 0}, { -0.705056079463317, 0.00448211481221729}, { -0.436957920272407, -0.370262236529651}, { -0.229712063674328, 0.0431705143488563}, { -0.148227797168837, 0.205722687925072}, { -0.393257971601542, 0.424195267916701}, { -0.413510880163265, 0.589027317989955}, { -0.431898814144998, 0.738680926783159}, { -0.283603628196569, 0.915912313032585}, { -0.0357952161759055, 0.912250885919817}, {0.219122757016883, 0.908484413381742}, {0.443769349276008, 0.835076661704473}, {0.426106787792343, 0.583529647320461}, {0.400589787646949, 0.220121134430258}, {0.160593774137044, 0.15625323679053}, {0.245514983733696, 0.0314675787386357}, {0.452432214072397, -0.272582526914925}, { 0.707859045957901, -0.00364987569003833}, {1, 0}}, { { -1, 0}, { -0.707920686483174, 0.00318900911649754}, { -0.434372174464315, -0.307446433658587}, { -0.22207624254243, 0.109425261995917}, { -0.137453117820789, 0.275594180895755}, { -0.340508174095858, 0.364631782467402}, { -0.369080584284576, 0.527714098008385}, { -0.383671882476694, 0.610996631060469}, { -0.233753076988816, 0.939761357928644}, { 0.0204626018463874, 0.936196353095824}, {0.268226367774715, 0.932721826949446}, {0.500766516589953, 0.908734435247741}, {0.488915515020803, 0.659928459184412}, {0.468202989215343, 0.225079120105809}, {0.106186153956061, 0.298643666003939}, {0.184680334657865, 0.170455849778656}, {0.39345790442032, -0.1704960590812}, { 0.713223372514099, -0.000707944210808817}, {1, 0}} }; if (i_pts_nbr != 7) return NULL; /* random shape */ uint8_t i_last_pt = (3 * (i_pts_nbr-1) + 1); uint8_t i_item = ((uint16_t) vlc_mrand48()) % NB_PRIM; point_t *ps_new_pt = (point_t *)malloc( sizeof( point_t ) * i_last_pt ); // sunqueen modify if (ps_new_pt == NULL) return NULL; if ((vlc_mrand48() & 1) == 1) for (uint8_t i=0; i < i_last_pt; i++) { ps_new_pt[i].f_x = ps_pt[i_item][i].f_x; ps_new_pt[i].f_y = ps_pt[i_item][i].f_y; } else for (uint8_t i=0; i < i_last_pt; i++) { ps_new_pt[i].f_x = ps_pt[i_item][i_last_pt-1-i].f_x; ps_new_pt[i].f_y = ps_pt[i_item][i_last_pt-1-i].f_y; } /* random shape size */ float f_current_scale = 0.7 + ( (float) (vlc_mrand48() % 1001 ) / 1000 )*0.3; for (uint8_t i_p = 0; i_p < i_last_pt; i_p++) { if ( i_p != 0 && i_p != 1 && i_p != i_last_pt - 2 && i_p != i_last_pt - 1 ) ps_new_pt[i_p].f_x = ps_new_pt[i_p].f_x * f_current_scale; ps_new_pt[i_p].f_y = ps_new_pt[i_p].f_y * f_current_scale; } /* random shape shift */ float f_offset = ( ( (float) (vlc_mrand48() % 1001 ) / 1000 ) - 0.5 ) * 0.2; for (uint8_t i=1; i < i_pts_nbr - 1; i++) { ps_new_pt[i*3-1].f_x += f_offset; ps_new_pt[i*3].f_x += f_offset; ps_new_pt[i*3+1].f_x += f_offset; } return ps_new_pt; }
/** * ProjectM update thread which do the rendering * @param p_this: the p_thread object */ static void *Thread( void *p_data ) { filter_t *p_filter = (filter_t*)p_data; filter_sys_t *p_sys = p_filter->p_sys; video_format_t fmt; vlc_gl_t *gl; unsigned int i_last_width = 0; unsigned int i_last_height = 0; locale_t loc; locale_t oldloc; projectM *p_projectm; #ifndef HAVE_PROJECTM2 char *psz_config; #else char *psz_preset_path; char *psz_title_font; char *psz_menu_font; projectM::Settings settings; #endif vlc_savecancel(); /* Create the openGL provider */ p_sys->p_vout = (vout_thread_t *)vlc_object_create( p_filter, sizeof(vout_thread_t) ); if( !p_sys->p_vout ) goto error; /* */ video_format_Init( &fmt, 0 ); video_format_Setup( &fmt, VLC_CODEC_RGB32, p_sys->i_width, p_sys->i_height, 0, 1 ); fmt.i_sar_num = 1; fmt.i_sar_den = 1; vout_display_state_t state; memset( &state, 0, sizeof(state) ); state.cfg.display.sar.num = 1; state.cfg.display.sar.den = 1; state.cfg.is_display_filled = true; state.cfg.zoom.num = 1; state.cfg.zoom.den = 1; state.sar.num = 1; state.sar.den = 1; p_sys->p_vd = vout_NewDisplay( p_sys->p_vout, &fmt, &state, "opengl", 300000, 1000000 ); if( !p_sys->p_vd ) { vlc_object_release( p_sys->p_vout ); goto error; } var_Create( p_sys->p_vout, "fullscreen", VLC_VAR_BOOL ); var_AddCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd ); gl = vout_GetDisplayOpengl( p_sys->p_vd ); if( !gl ) { vout_DeleteDisplay( p_sys->p_vd, NULL ); vlc_object_release( p_sys->p_vout ); goto error; } /* Work-around the projectM locale bug */ loc = newlocale (LC_NUMERIC_MASK, "C", NULL); oldloc = uselocale (loc); /* Create the projectM object */ #ifndef HAVE_PROJECTM2 psz_config = var_InheritString( p_filter, "projectm-config" ); p_projectm = new projectM( psz_config ); free( psz_config ); #else psz_preset_path = var_InheritString( p_filter, "projectm-preset-path" ); #ifdef WIN32 if ( psz_preset_path == NULL ) { char *psz_data_path = config_GetDataDir( p_filter ); asprintf( &psz_preset_path, "%s" DIR_SEP "visualization", psz_data_path ); free( psz_data_path ); } #endif psz_title_font = var_InheritString( p_filter, "projectm-title-font" ); psz_menu_font = var_InheritString( p_filter, "projectm-menu-font" ); settings.meshX = var_InheritInteger( p_filter, "projectm-meshx" ); settings.meshY = var_InheritInteger( p_filter, "projectm-meshy" ); settings.fps = 35; settings.textureSize = var_InheritInteger( p_filter, "projectm-texture-size" ); settings.windowWidth = p_sys->i_width; settings.windowHeight = p_sys->i_height; settings.presetURL = psz_preset_path; settings.titleFontURL = psz_title_font; settings.menuFontURL = psz_menu_font; settings.smoothPresetDuration = 5; settings.presetDuration = 30; settings.beatSensitivity = 10; settings.aspectCorrection = 1; settings.easterEgg = 1; settings.shuffleEnabled = 1; p_projectm = new projectM( settings ); free( psz_menu_font ); free( psz_title_font ); free( psz_preset_path ); #endif /* HAVE_PROJECTM2 */ p_sys->i_buffer_size = p_projectm->pcm()->maxsamples; p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size, sizeof( float ) ); vlc_sem_post( &p_sys->ready ); /* Choose a preset randomly or projectM will always show the first one */ if ( p_projectm->getPlaylistSize() > 0 ) p_projectm->selectPreset( (unsigned)vlc_mrand48() % p_projectm->getPlaylistSize() ); /* */ for( ;; ) { const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */ /* Manage the events */ vout_ManageDisplay( p_sys->p_vd, true ); if( p_sys->p_vd->cfg->display.width != i_last_width || p_sys->p_vd->cfg->display.height != i_last_height ) { /* FIXME it is not perfect as we will have black bands */ vout_display_place_t place; vout_display_PlacePicture( &place, &p_sys->p_vd->source, p_sys->p_vd->cfg, false ); p_projectm->projectM_resetGL( place.width, place.height ); i_last_width = p_sys->p_vd->cfg->display.width; i_last_height = p_sys->p_vd->cfg->display.height; } /* Render the image and swap the buffers */ vlc_mutex_lock( &p_sys->lock ); if( p_sys->i_nb_samples > 0 ) { p_projectm->pcm()->addPCMfloat( p_sys->p_buffer, p_sys->i_nb_samples ); p_sys->i_nb_samples = 0; } if( p_sys->b_quit ) { vlc_mutex_unlock( &p_sys->lock ); delete p_projectm; vout_DeleteDisplay( p_sys->p_vd, NULL ); vlc_object_release( p_sys->p_vout ); if (loc != (locale_t)0) { uselocale (oldloc); freelocale (loc); } return NULL; } vlc_mutex_unlock( &p_sys->lock ); p_projectm->renderFrame(); /* */ mwait( i_deadline ); if( !vlc_gl_Lock(gl) ) { vlc_gl_Swap( gl ); vlc_gl_Unlock( gl ); } } abort(); error: p_sys->b_error = true; vlc_sem_post( &p_sys->ready ); return NULL; }
/***************************************************************************** * puzzle_auto_shuffle: shuffle the pieces on the desk depending on * auto_shuffle_speed parameter * = random move of one piece each time * auto_shuffle_countdown is < 0 *****************************************************************************/ void puzzle_auto_shuffle( filter_t *p_filter) { filter_sys_t *p_sys = p_filter->p_sys; if ( p_sys->s_current_param.i_auto_shuffle_speed < 500 ) return; if ( --p_sys->i_auto_shuffle_countdown_val > 0 ) return; /* delay reached, preset next delay and proceed with puzzle_auto_shuffle */ p_sys->i_auto_shuffle_countdown_val = init_countdown(p_sys->s_current_param.i_auto_shuffle_speed); /* random piece to be moved */ int32_t i_start = ((unsigned)vlc_mrand48()) % p_sys->s_allocated.i_pieces_nbr; for (uint32_t i_l = 0; i_l < p_sys->s_allocated.i_pieces_nbr; i_l++){ int32_t i = ( i_l + i_start ) % p_sys->s_allocated.i_pieces_nbr; /* find one piece which is part of one group */ if ( p_sys->pi_group_qty[p_sys->ps_pieces[i].i_group_ID] > 1 ) { /* find an empty group to be used by this dismantled piece */ uint32_t i_new_group; for ( i_new_group = 0 ; i_new_group < p_sys->s_allocated.i_pieces_nbr ; i_new_group ++ ) if ( p_sys->pi_group_qty[i_new_group] == 0 ) break; p_sys->ps_pieces[i].i_group_ID = i_new_group; p_sys->ps_pieces[i].b_finished = false; /* random rotate & mirror */ switch ( p_sys->s_current_param.i_rotate ) { case 1: puzzle_rotate_pce( p_filter, i, (( (unsigned) vlc_mrand48()) % ( 2 ) ) * 2, p_sys->ps_pieces[i].i_center_x, p_sys->ps_pieces[i].i_center_y, false ); break; case 2: puzzle_rotate_pce( p_filter, i, (( (unsigned) vlc_mrand48()) % ( 4 ) ), p_sys->ps_pieces[i].i_center_x, p_sys->ps_pieces[i].i_center_y, false ); break; case 3: puzzle_rotate_pce( p_filter, i, (( (unsigned) vlc_mrand48()) % ( 8 ) ), p_sys->ps_pieces[i].i_center_x, p_sys->ps_pieces[i].i_center_y, false ); break; } /* random mvt */ p_sys->ps_pieces[i].ps_piece_in_plane[0].i_actual_x = p_sys->ps_desk_planes[0].i_border_width + ( (unsigned) vlc_mrand48()) % ( p_sys->ps_desk_planes[0].i_width - 2*p_sys->ps_desk_planes[0].i_border_width - p_sys->ps_pieces[i].ps_piece_in_plane[0].i_width) + p_sys->ps_pieces[i].ps_piece_in_plane[0].i_width / 2 * ( 1 - p_sys->ps_pieces[i].i_step_x_x ) - (p_sys->ps_pieces[i].ps_piece_in_plane[0].i_lines / 2) * p_sys->ps_pieces[i].i_step_y_x; p_sys->ps_pieces[i].ps_piece_in_plane[0].i_actual_y = p_sys->ps_desk_planes[0].i_border_lines + ( (unsigned) vlc_mrand48()) % ( p_sys->ps_desk_planes[0].i_lines - 2*p_sys->ps_desk_planes[0].i_border_lines - p_sys->ps_pieces[i].ps_piece_in_plane[0].i_lines) + p_sys->ps_pieces[i].ps_piece_in_plane[0].i_lines / 2 * ( 1 - p_sys->ps_pieces[i].i_step_y_y ) - (p_sys->ps_pieces[i].ps_piece_in_plane[0].i_width / 2) * p_sys->ps_pieces[i].i_step_x_y; /* redefine shapes */ uint32_t i_left_pce = 0; uint32_t i_right_pce = 6; uint32_t i_top_pce = 2; uint32_t i_btm_pce = 4; uint32_t i_pce = 0; for (int32_t i_row = 0; i_row < p_sys->s_allocated.i_rows; i_row++) for (int32_t i_col = 0; i_col < p_sys->s_allocated.i_cols; i_col++) { if (p_sys->ps_pieces[i].i_original_row == p_sys->ps_pieces[i_pce].i_original_row) { if (p_sys->ps_pieces[i].i_original_col == p_sys->ps_pieces[i_pce].i_original_col - 1) i_right_pce = i_pce; else if (p_sys->ps_pieces[i].i_original_col == p_sys->ps_pieces[i_pce].i_original_col + 1) i_left_pce = i_pce; } else if (p_sys->ps_pieces[i].i_original_col == p_sys->ps_pieces[i_pce].i_original_col) { if (p_sys->ps_pieces[i].i_original_row == p_sys->ps_pieces[i_pce].i_original_row - 1) i_btm_pce = i_pce; else if (p_sys->ps_pieces[i].i_original_row == p_sys->ps_pieces[i_pce].i_original_row + 1) i_top_pce = i_pce; } i_pce++; } if ((p_sys->ps_pieces[i].i_left_shape == 0) && (p_sys->ps_pieces[i].i_original_col != 0)) { p_sys->ps_pieces[i_left_pce].i_right_shape = 6 + 8 + 8*(( (unsigned) vlc_mrand48()) % ( SHAPES_QTY ) ) + (vlc_mrand48() & 0x01); p_sys->ps_pieces[i].i_left_shape = (p_sys->ps_pieces[i_left_pce].i_right_shape - 6 ) ^ 0x01; } if ((p_sys->ps_pieces[i].i_right_shape == 6) && (p_sys->ps_pieces[i].i_original_col != p_sys->s_allocated.i_cols-1)) { p_sys->ps_pieces[i].i_right_shape = 6 + 8 + 8*(( (unsigned) vlc_mrand48()) % ( SHAPES_QTY ) ) + (vlc_mrand48() & 0x01); p_sys->ps_pieces[i_right_pce].i_left_shape = (p_sys->ps_pieces[i].i_right_shape - 6 ) ^ 0x01; } if ((p_sys->ps_pieces[i].i_top_shape == 2) && (p_sys->ps_pieces[i].i_original_row != 0)) { p_sys->ps_pieces[i_top_pce].i_btm_shape = 4 + 8 + 8*(( (unsigned) vlc_mrand48()) % ( SHAPES_QTY ) ) + (vlc_mrand48() & 0x01); p_sys->ps_pieces[i].i_top_shape = (p_sys->ps_pieces[i_top_pce].i_btm_shape - 2 ) ^ 0x01; } if ((p_sys->ps_pieces[i].i_btm_shape == 4) && (p_sys->ps_pieces[i].i_original_row != p_sys->s_allocated.i_rows-1)) { p_sys->ps_pieces[i].i_btm_shape = 4 + 8 + 8*(( (unsigned) vlc_mrand48()) % ( SHAPES_QTY ) ) + (vlc_mrand48() & 0x01); p_sys->ps_pieces[i_btm_pce].i_top_shape = (p_sys->ps_pieces[i].i_btm_shape - 2 ) ^ 0x01; } puzzle_calculate_corners( p_filter, i ); break; } } }
/***************************************************************************** * puzzle_bake_piece: compute data dedicated to each piece *****************************************************************************/ int puzzle_bake_piece( filter_t *p_filter) { int i_ret = puzzle_allocate_ps_pieces( p_filter); if (i_ret != VLC_SUCCESS) return i_ret; filter_sys_t *p_sys = p_filter->p_sys; /* generates random pi_order array */ i_ret = puzzle_shuffle( p_filter ); if (i_ret != VLC_SUCCESS) return i_ret; int32_t i = 0; for (int32_t row = 0; row < p_sys->s_allocated.i_rows; row++) { for (int32_t col = 0; col < p_sys->s_allocated.i_cols; col++) { int32_t orow = row; int32_t ocol = col; if (p_sys->pi_order != NULL) { orow = p_sys->pi_order[i] / (p_sys->s_allocated.i_cols); ocol = p_sys->pi_order[i] % (p_sys->s_allocated.i_cols); } p_sys->ps_pieces[i].i_original_row = orow; p_sys->ps_pieces[i].i_original_col = ocol; /* set bottom and right shapes */ p_sys->ps_pieces[i].i_left_shape = 0; p_sys->ps_pieces[i].i_top_shape = 2; p_sys->ps_pieces[i].i_btm_shape = 4; p_sys->ps_pieces[i].i_right_shape = 6; if (p_sys->s_allocated.i_shape_size > 0) { if (orow < p_sys->s_allocated.i_rows - 1) p_sys->ps_pieces[i].i_btm_shape = 4 + 8 + 8*(( (unsigned) vlc_mrand48()) % ( SHAPES_QTY ) ) + (vlc_mrand48() & 0x01); if (ocol < p_sys->s_allocated.i_cols - 1) p_sys->ps_pieces[i].i_right_shape = 6 + 8 + 8*(( (unsigned) vlc_mrand48()) % ( SHAPES_QTY ) ) + (vlc_mrand48() & 0x01); } /* set piece data */ p_sys->ps_pieces[i].i_actual_angle = 0; p_sys->ps_pieces[i].b_overlap = false; p_sys->ps_pieces[i].i_actual_mirror = +1; p_sys->ps_pieces[i].b_finished = ((ocol == col) && (orow == row)); p_sys->ps_pieces[i].i_group_ID = i; /* add small random offset to location */ int32_t i_rand_x = 0; int32_t i_rand_y = 0; if (p_sys->s_current_param.b_advanced) { i_rand_x = (( (unsigned) vlc_mrand48()) % ( p_sys->ps_desk_planes[0].i_pce_max_width + 1 ) ) - (int32_t) p_sys->ps_desk_planes[0].i_pce_max_width / 2; i_rand_y = (( (unsigned) vlc_mrand48()) % ( p_sys->ps_desk_planes[0].i_pce_max_lines + 1 ) ) - (int32_t) p_sys->ps_desk_planes[0].i_pce_max_lines / 2; } /* copy related puzzle data to piece data */ if (p_sys->ps_puzzle_array != NULL) { for (uint8_t i_plane = 0; i_plane < p_sys->s_allocated.i_planes; i_plane++) { p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_width = p_sys->ps_puzzle_array[row][col][i_plane].i_width; p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_lines = p_sys->ps_puzzle_array[row][col][i_plane].i_lines; p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_original_x = p_sys->ps_puzzle_array[orow][ocol][i_plane].i_x; p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_original_y = p_sys->ps_puzzle_array[orow][ocol][i_plane].i_y; p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_actual_x = p_sys->ps_puzzle_array[row][col][i_plane].i_x + i_rand_x * p_sys->ps_desk_planes[i_plane].i_width / p_sys->ps_desk_planes[0].i_width; p_sys->ps_pieces[i].ps_piece_in_plane[i_plane].i_actual_y = p_sys->ps_puzzle_array[row][col][i_plane].i_y + i_rand_y * p_sys->ps_desk_planes[i_plane].i_lines / p_sys->ps_desk_planes[0].i_lines; if (i_plane == 0) { p_sys->ps_pieces[i].i_OLx = p_sys->ps_pieces[i].ps_piece_in_plane[0].i_original_x; p_sys->ps_pieces[i].i_OTy = p_sys->ps_pieces[i].ps_piece_in_plane[0].i_original_y; p_sys->ps_pieces[i].i_ORx = p_sys->ps_pieces[i].ps_piece_in_plane[0].i_original_x + p_sys->ps_pieces[i].ps_piece_in_plane[0].i_width - 1; p_sys->ps_pieces[i].i_OBy = p_sys->ps_pieces[i].ps_piece_in_plane[0].i_original_y + p_sys->ps_pieces[i].ps_piece_in_plane[0].i_lines - 1; puzzle_calculate_corners( p_filter, i ); } } } i++; } } /* left and top shapes are based on negative right and bottom ones */ puzzle_set_left_top_shapes( p_filter); /* add random rotation to each piece */ puzzle_random_rotate( p_filter); return VLC_SUCCESS; }
static void input_item_add_subitem_tree ( const vlc_event_t * p_event, void * user_data ) { input_item_t *p_input = p_event->p_obj; playlist_t *p_playlist = (( playlist_item_t* ) user_data)->p_playlist; input_item_node_t *p_new_root = p_event->u.input_item_subitem_tree_added.p_root; PL_LOCK; playlist_item_t *p_item = playlist_ItemGetByInput( p_playlist, p_input ); assert( p_item != NULL ); bool b_current = get_current_status_item( p_playlist ) == p_item; bool b_autostart = var_GetBool( p_playlist, "playlist-autostart" ); bool b_stop = p_item->i_flags & PLAYLIST_SUBITEM_STOP_FLAG; bool b_flat = false; p_item->i_flags &= ~PLAYLIST_SUBITEM_STOP_FLAG; /* We will have to flatten the tree out if we are in "the playlist" node and the user setting demands flat playlist */ if( !pl_priv(p_playlist)->b_tree ) { playlist_item_t *p_up = p_item; while( p_up->p_parent ) { if( p_up->p_parent == p_playlist->p_playing ) { b_flat = true; break; } p_up = p_up->p_parent; } } int pos = 0; /* If we have to flatten out, then take the item's position in the parent as insertion point and delete the item */ if( b_flat ) { playlist_item_t *p_parent = p_item->p_parent; assert( p_parent != NULL ); int i; for( i = 0; i < p_parent->i_children; i++ ) { if( p_parent->pp_children[i] == p_item ) { pos = i; break; } } assert( i < p_parent->i_children ); playlist_DeleteItem( p_playlist, p_item, true ); p_item = p_parent; } else { pos = p_item->i_children >= 0 ? p_item->i_children : 0; } /* At this point: "p_item" is the node where sub-items should be inserted, "pos" is the insertion position in that node */ int last_pos = playlist_InsertInputItemTree( p_playlist, p_item, p_new_root, pos, b_flat ); if( !b_flat ) var_SetInteger( p_playlist, "leaf-to-parent", p_item->i_id ); //control playback only if it was the current playing item that got subitems if( b_current ) { if( last_pos == pos || ( b_stop && !b_flat ) || !b_autostart ) { /* We stop, either because no sub-item was actually created, or some flags/settings want us to do so at this point */ PL_UNLOCK; playlist_Stop( p_playlist ); return; } else { /* Continue to play, either random or the first new item */ playlist_item_t *p_play_item; if( var_GetBool( p_playlist, "random" ) ) { unsigned rand_pos = ((unsigned)vlc_mrand48()) % (last_pos - pos); rand_pos += pos; p_play_item = p_item->pp_children[rand_pos]; } else { p_play_item = p_item->pp_children[pos]; /* NOTE: this is a work around the general bug: if node-to-be-played contains sub-nodes, then second instead of first leaf starts playing (only in case the leafs have just been instered and playlist has not yet been rebuilt.) */ while( p_play_item->i_children > 0 ) p_play_item = p_play_item->pp_children[0]; } playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, get_current_status_node( p_playlist ), p_play_item ); } } PL_UNLOCK; }
/** * ProjectM update thread which do the rendering * @param p_this: the p_thread object */ static void *Thread( void *p_data ) { filter_t *p_filter = (filter_t*)p_data; filter_sys_t *p_sys = p_filter->p_sys; vlc_gl_t *gl = p_sys->gl; locale_t loc; locale_t oldloc; projectM *p_projectm; #ifndef HAVE_PROJECTM2 char *psz_config; #else char *psz_preset_path; char *psz_title_font; char *psz_menu_font; projectM::Settings settings; #endif vlc_gl_MakeCurrent( gl ); /* Work-around the projectM locale bug */ loc = newlocale (LC_NUMERIC_MASK, "C", NULL); oldloc = uselocale (loc); /* Create the projectM object */ #ifndef HAVE_PROJECTM2 psz_config = var_InheritString( p_filter, "projectm-config" ); p_projectm = new projectM( psz_config ); free( psz_config ); #else psz_preset_path = var_InheritString( p_filter, "projectm-preset-path" ); #ifdef _WIN32 if ( psz_preset_path == NULL ) { char *psz_data_path = config_GetDataDir(); asprintf( &psz_preset_path, "%s" DIR_SEP "visualization", psz_data_path ); free( psz_data_path ); } #endif psz_title_font = var_InheritString( p_filter, "projectm-title-font" ); psz_menu_font = var_InheritString( p_filter, "projectm-menu-font" ); settings.meshX = var_InheritInteger( p_filter, "projectm-meshx" ); settings.meshY = var_InheritInteger( p_filter, "projectm-meshy" ); settings.fps = 35; settings.textureSize = var_InheritInteger( p_filter, "projectm-texture-size" ); settings.windowWidth = var_InheritInteger( p_filter, "projectm-width" ); settings.windowHeight = var_CreateGetInteger( p_filter, "projectm-height" ); settings.presetURL = psz_preset_path; settings.titleFontURL = psz_title_font; settings.menuFontURL = psz_menu_font; settings.smoothPresetDuration = 5; settings.presetDuration = 30; settings.beatSensitivity = 10; settings.aspectCorrection = 1; settings.easterEgg = 1; settings.shuffleEnabled = 1; settings.softCutRatingsEnabled= false; p_projectm = new projectM( settings ); free( psz_menu_font ); free( psz_title_font ); free( psz_preset_path ); #endif /* HAVE_PROJECTM2 */ p_sys->i_buffer_size = p_projectm->pcm()->maxsamples; p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size, sizeof( float ) ); /* Choose a preset randomly or projectM will always show the first one */ if ( p_projectm->getPlaylistSize() > 0 ) p_projectm->selectPreset( (unsigned)vlc_mrand48() % p_projectm->getPlaylistSize() ); /* */ for( ;; ) { const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */ /* Manage the events */ unsigned width, height; bool quit; if( vlc_gl_surface_CheckSize( gl, &width, &height ) ) p_projectm->projectM_resetGL( width, height ); /* Render the image and swap the buffers */ vlc_mutex_lock( &p_sys->lock ); if( p_sys->i_nb_samples > 0 ) { p_projectm->pcm()->addPCMfloat( p_sys->p_buffer, p_sys->i_nb_samples ); p_sys->i_nb_samples = 0; } quit = p_sys->b_quit; vlc_mutex_unlock( &p_sys->lock ); if( quit ) break; p_projectm->renderFrame(); /* */ mwait( i_deadline ); if( !vlc_gl_Lock(gl) ) { vlc_gl_Swap( gl ); vlc_gl_Unlock( gl ); } } delete p_projectm; if (loc != (locale_t)0) { uselocale (oldloc); freelocale (loc); } vlc_gl_ReleaseCurrent( gl ); return NULL; }