Ticket #1424: mplayer-shuffle.diff
| File mplayer-shuffle.diff, 4.2 KB (added by , 14 years ago) |
|---|
-
playtree.c
221 221 222 222 } 223 223 224 static play_tree_t* 225 play_tree_shuffle(play_tree_t* head) { 226 play_tree_t* iter; 227 play_tree_t** list; 228 int i, r; 229 int count = 1; 230 231 while (head->prev) 232 head = head->prev; 233 234 iter = head; 235 while (iter = iter->next) 236 count++; 237 238 if (count <= 1) 239 return head; 240 241 list = malloc(count * sizeof(*list)); 242 if (list == NULL) { 243 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory to shuffle playlist\n",(int)sizeof(*list) * count); 244 return head; 245 } 246 247 for (i = 0, iter = head; i < count; i++) { 248 list[i] = iter; 249 iter = iter->next; 250 } 251 252 // shuffle 253 for (i = count - 1; i > 0; i--) { 254 r = (int)((float)(i) * rand() / (RAND_MAX + 1.0)); 255 iter = list[i]; 256 list[i] = list[r]; 257 list[r] = iter; 258 } 259 260 // rebuild playtree 261 for (i = 0; i < count; i++) { 262 list[i]->prev = NULL; 263 list[i]->next = NULL; 264 } 265 266 head = list[0]; 267 for (i = 1; i < count; i++) { 268 play_tree_append_entry(head, list[i]); 269 head = list[i]; 270 } 271 272 head = list[0]; 273 play_tree_set_parent(head, head->parent); 274 275 free(list); 276 277 return head; 278 } 279 224 280 void 225 281 play_tree_set_child(play_tree_t* pt, play_tree_t* child) { 226 282 play_tree_t* iter; … … 517 573 free(iter); 518 574 } 519 575 520 static play_tree_t*521 play_tree_rnd_step(play_tree_t* pt) {522 int count = 0;523 int r;524 play_tree_t *i,*head;525 576 526 // Count how many free choice we have527 for(i = pt ; i->prev ; i = i->prev)528 if(!(i->flags & PLAY_TREE_RND_PLAYED)) count++;529 head = i;530 if(!(i->flags & PLAY_TREE_RND_PLAYED)) count++;531 for(i = pt->next ; i ; i = i->next)532 if(!(i->flags & PLAY_TREE_RND_PLAYED)) count++;533 534 if(!count) return NULL;535 536 r = (int)((float)(count) * rand() / (RAND_MAX + 1.0));537 538 for(i = head ; i ; i=i->next) {539 if(!(i->flags & PLAY_TREE_RND_PLAYED)) r--;540 if(r < 0) return i;541 }542 543 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Random stepping error\n");544 return NULL;545 }546 547 548 577 int 549 578 play_tree_iter_step(play_tree_iter_t* iter, int d,int with_nodes) { 550 play_tree_t * pt;579 play_tree_t *pt, *parent; 551 580 552 581 if ( !iter ) return PLAY_TREE_ITER_ENTRY; 553 582 if ( !iter->root ) return PLAY_TREE_ITER_ENTRY; … … 568 597 m_config_pop(iter->config); 569 598 } 570 599 571 if(iter->tree->parent && (iter->tree->parent->flags & PLAY_TREE_RND)) 572 iter->mode = PLAY_TREE_ITER_RND; 573 else 574 iter->mode = PLAY_TREE_ITER_NORMAL; 600 parent = iter->tree->parent; 601 if(parent && (parent->flags & PLAY_TREE_RND)) { 602 iter->tree = play_tree_shuffle(iter->tree); 603 parent->flags &= ~PLAY_TREE_RND; 604 } 575 605 576 606 iter->file = -1; 577 if(iter->mode == PLAY_TREE_ITER_RND) 578 pt = play_tree_rnd_step(iter->tree); 579 else if( d > 0 ) { 607 pt = iter->tree; 608 if( d > 0 ) { 580 609 int i; 581 pt = iter->tree;582 610 for(i = d ; i > 0 && pt ; i--) 583 611 pt = pt->next; 584 612 d = i ? i : 1; 585 613 } else if(d < 0) { 586 614 int i; 587 pt = iter->tree;588 615 for(i = d ; i < 0 && pt ; i++) 589 616 pt = pt->prev; 590 617 d = i ? i : -1; 591 } else 592 pt = iter->tree; 618 } 593 619 594 620 if(pt == NULL) { // No next 595 621 // Must we loop? 596 if (iter->mode == PLAY_TREE_ITER_RND) {597 if (iter->root->loop == 0)598 return PLAY_TREE_ITER_END;599 play_tree_unset_flag(iter->root, PLAY_TREE_RND_PLAYED, -1);600 if (iter->root->loop > 0) iter->root->loop--;601 // try again602 return play_tree_iter_step(iter, 0, with_nodes);603 } else604 622 if(iter->tree->parent && iter->tree->parent->loop != 0 && ((d > 0 && iter->loop != 0) || ( d < 0 && (iter->loop < 0 || iter->loop < iter->tree->parent->loop) ) ) ) { 605 623 if(d > 0) { // Go back to the first one 606 624 for(pt = iter->tree ; pt->prev != NULL; pt = pt->prev) … … 650 668 if(iter->config) { 651 669 play_tree_iter_push_params(iter); 652 670 iter->entry_pushed = 1; 653 if(iter->mode == PLAY_TREE_ITER_RND)654 pt->flags |= PLAY_TREE_RND_PLAYED;655 671 } 656 672 657 673 return PLAY_TREE_ITER_ENTRY; … … 717 733 // Pop subtree params 718 734 if(iter->config) { 719 735 m_config_pop(iter->config); 720 if(iter->mode == PLAY_TREE_ITER_RND)721 iter->tree->flags |= PLAY_TREE_RND_PLAYED;722 736 } 723 737 724 738 return play_tree_iter_step(iter,d,with_nodes);
