📄 playlist.c
字号:
#include <string.h>#include "as31glue.h"#include "printf.h"#include "paulmon2.h"#include "display.h"#include "malloc.h"#include "dirlist.h"#include "playlist.h"#include "stricmp.h"#include "rand.h"#include "main.h"simm_id current_playlist;simm_id first_playlist;simm_id last_playlist;simm_id start_rand_playlist;simm_id head_rand_playlist;simm_id tail_rand_playlist;simm_id start_all_rand;simm_id head_all_rand;simm_id tail_all_rand;unsigned int num_unrand_lists;unsigned int num_unrand_all_files;static playlist_list_t *dirrand_current_list;static unsigned int addr6_backup, addr7_backup;play_modes_t play_mode;static void dirrand_initialize(void);static simm_id dirrand_new_list(simm_id /* playlist_list_t */ list_id, unsigned char use_current_file);static void dirrand_randomize_incremental(simm_id /* playlist_t */ current);static void plstrand_initialize(void);static void plstrand_randomize_incremental(simm_id /* playlist_list_t */ list_id);static void allrand_initialize(void);static void allrand_randomize_incremental(simm_id /* playlist_list_t */ list_id);// #define VERBOSE_DEBUGvoid playlist_init(void){ first_playlist=0; last_playlist=0; current_playlist=0;}extern data simm_id temp_id;void playlist_create(simm_id pl_name) { // simm_id temp_id; playlist_list_t * pl_l_struct; temp_id = simm_malloc((unsigned int)(sizeof(struct playlist_list_struct))); if(first_playlist == 0) { first_playlist = temp_id; last_playlist = temp_id; pl_l_struct = addr6(temp_id); pl_l_struct->prev_sequential = 0; } else { pl_l_struct = Addr6(last_playlist); pl_l_struct->next_sequential = temp_id; pl_l_struct = addr6(temp_id); pl_l_struct->prev_sequential = last_playlist; last_playlist = temp_id; } current_playlist = temp_id; pl_l_struct->next_sequential = 0; pl_l_struct->playlist_start_sequential = 0; pl_l_struct->playlist_end_sequential = 0; pl_l_struct->num_unrand_files = 0; pl_l_struct->name = pl_name; //printf("playlist %s created\r\n", Addr6(pl_name));}void playlist_add_file(simm_id /* struct filelist_struct */ fl_rec) // Add file to current playlist{ // xdata simm_id temp_id; playlist_list_t * pl_l_struct; playlist_t * pl_struct; filelist_t * fl_struct; pl_l_struct = Addr6(current_playlist); pl_l_struct->num_unrand_files++; temp_id = simm_malloc((unsigned int)(sizeof(struct playlist_struct))); if (pl_l_struct->playlist_start_sequential == 0) { pl_l_struct->playlist_start_sequential = temp_id; pl_l_struct->playlist_end_sequential = temp_id; pl_struct = addr7(temp_id); memset(pl_struct, 0, sizeof(struct playlist_struct)); pl_struct->prev_sequential = 0; // done by memset } else { pl_struct = Addr7(pl_l_struct->playlist_end_sequential); pl_struct->next_sequential = temp_id; pl_struct = addr7(temp_id); memset(pl_struct, 0, sizeof(struct playlist_struct)); pl_struct->prev_sequential = pl_l_struct->playlist_end_sequential; pl_l_struct->playlist_end_sequential = temp_id; } pl_struct->playlist = current_playlist; pl_struct->next_sequential = 0; // done by memset pl_struct->fl_rec = fl_rec; fl_struct = Addr6(fl_rec); fl_struct->pl_entry = temp_id;}void playlist_show(void) // Shows the Current Playlist{ playlist_t * pl_struct; filelist_t * fl_struct; temp_id = ((playlist_list_t *)Addr7(current_playlist))->playlist_start_sequential; while(temp_id != 0) { pl_struct = addr6(temp_id); fl_struct = Addr7(pl_struct->fl_rec); print_hex32(pl_struct->prev_sequential); print_hex32(temp_id); print_hex32(pl_struct->next_sequential); print_str(Addr6(fl_struct->long_name)); print_crlf(); temp_id = ((playlist_t *)addr6(temp_id))->next_sequential; }}void playlist_delete(playlist_list_t *p){ print("deleting empty playlist: "); print_str(Addr7(p->name)); print_crlf(); if (p->prev_sequential) { ((playlist_list_t *)Addr7(p->prev_sequential))->next_sequential = p->next_sequential; } else { first_playlist = p->next_sequential; } if (p->next_sequential) { ((playlist_list_t *)Addr7(p->next_sequential))->prev_sequential = p->prev_sequential; } else { last_playlist = p->next_sequential; } simm_free(simm_id_from_pointer(p));}void playlist_purge_empty(void){ playlist_list_t * pl_l_struct; temp_id = first_playlist; while (temp_id) { pl_l_struct = addr6(temp_id); temp_id = pl_l_struct->next_sequential; if (pl_l_struct->playlist_start_sequential == 0) { playlist_delete(pl_l_struct); } }}void playlist_show_all() // Show all playlists{ playlist_list_t * pl_l_struct; current_playlist = first_playlist; while (current_playlist != 0) { pl_l_struct = Addr6(current_playlist); print("\r\nPlaylist: "); print_hex32(pl_l_struct->prev_sequential); print_hex32(current_playlist); print_hex32(pl_l_struct->next_sequential); print("\""); print_str(Addr7(pl_l_struct->name)); print("\"\r\n"); playlist_show(); print_crlf(); pl_l_struct = Addr6(current_playlist); current_playlist = pl_l_struct->next_sequential; } current_playlist = first_playlist; // Reset to first}void play_mode_change(void){ switch (play_mode) { case MODE_DIRONLY: // sequential within one directory case MODE_SEQNTIAL: // sequential among all directories break; case MODE_PLSTRAND: // seq within each dir, choose dirs randomly plstrand_initialize(); update_rand_seed_needed = 1; break; case MODE_DIRRAND: // randomly choose files within 1 dir dirrand_initialize(); update_rand_seed_needed = 1; break; case MODE_ALLRAND: // randomly choose files among all dirs case MODE_KEYRAND: // play all files sequentially until a key is pressed allrand_initialize(); update_rand_seed_needed = 1; break; default: break; } update_mode_needed = 1; update_playlist_state_needed = 1; param_restart_write_timer(15);}void save_play_mode(void){ ibuf[0] = play_mode; write_flash_param(PARAM_PLAY_MODE, ibuf); update_mode_needed = 0; print("saved play mode = "); print_hex16(play_mode); print_crlf();}void play_mode_toggle(void){ if (play_mode == MODE_SEQNTIAL) { play_mode = MODE_ALLRAND; } else { play_mode = MODE_SEQNTIAL; } play_mode_change();}void play_mode_next(void){ printf("play_mode = %d\r\n", play_mode); if (play_mode >= MODE_MAX) { play_mode = MODE_MIN; } else { play_mode++; } printf("play_mode = %d\r\n", play_mode); play_mode_change();}void play_mode_prev(void){ if (play_mode <= MODE_MIN) { play_mode = MODE_MAX; } else { play_mode--; } play_mode_change();}void play_mode_set(play_modes_t new_play_mode){ play_mode = new_play_mode; play_mode_change();}#pragma CALLEE-SAVES sdcc_bug_587536_workaroundstatic void sdcc_bug_587536_workaround(void xdata *p){ p; }/*simm_id file_ptr(playlist_t *p, xdata int file_num){ int i; playlist_t for(i=file_num;i!=0;i++) { } }*/simm_id next_file_ptr(playlist_t *p, unsigned char keyflag){ #ifdef VERBOSE_DEBUG print("begin next_file_ptr, p="); print_hex32(simm_id_from_pointer(p)); print_crlf(); #endif switch (play_mode) { case MODE_DIRONLY: // sequential within one directory if (p->next_sequential) { return p->next_sequential; } else { return ((playlist_list_t *)Addr6(p->playlist))->playlist_start_sequential; } case MODE_SEQNTIAL: // sequential among all directories case MODE_PLSTRAND: // seq within each dir, choose dirs randomly if (p->next_sequential) { return p->next_sequential; } else { return next_playlist_ptr(p, 0); } case MODE_DIRRAND: // randomly choose files within 1 dir if (p->next_random == 0) { dirrand_randomize_incremental(simm_id_from_pointer(p)); } sdcc_bug_587536_workaround(p); return p->next_random; case MODE_KEYRAND: // play all files sequentially until a key is pressed if (keyflag == 0) { // no key pressed so act as MODE_SEQNTIAL if (p->next_sequential) { return p->next_sequential; } else { return next_playlist_ptr(p, 0); } } sdcc_bug_587536_workaround(p); // else fall through case MODE_ALLRAND: // randomly choose files among all dirs if (p->next_random == 0) { allrand_randomize_incremental(simm_id_from_pointer(p)); } sdcc_bug_587536_workaround(p); return p->next_random; default: break; } return 0;}simm_id prev_file_ptr(playlist_t *p){ switch (play_mode) { case MODE_DIRONLY: // sequential within one directory if (p->prev_sequential) { return p->prev_sequential; } else { return ((playlist_list_t *)Addr6(p->playlist))->playlist_end_sequential; } case MODE_SEQNTIAL: // sequential among all directories case MODE_PLSTRAND: // seq within each dir, choose dirs randomly if (p->prev_sequential) { return p->prev_sequential; } else { p = (playlist_t *)addr6(prev_playlist_ptr(p)); return ((playlist_list_t *)Addr6(p->playlist))->playlist_end_sequential; } case MODE_DIRRAND: // randomly choose files within 1 dir if (p->prev_random == 0) { dirrand_randomize_incremental(simm_id_from_pointer(p)); } sdcc_bug_587536_workaround(p); return p->prev_random; case MODE_KEYRAND: // play all files sequentially until a key is pressed // no decision, must be here due to keypress case MODE_ALLRAND: // randomly choose files among all dirs if (p->prev_random == 0) { allrand_randomize_incremental(simm_id_from_pointer(p)); } sdcc_bug_587536_workaround(p); return p->prev_random; default: break; } return 0;}simm_id next_playlist_ptr(playlist_t *p, unsigned char keyflag){ playlist_list_t *list; list = (playlist_list_t *)Addr6(p->playlist); switch (play_mode) { case MODE_KEYRAND: // play all files sequentially until a key is pressed if (keyflag != 0) { // keypress so act as MODE_ALLRAND return next_file_ptr(p, 1); } // else fall through case MODE_DIRONLY: // sequential within one directory case MODE_SEQNTIAL: // sequential among all directories if (list->next_sequential) { return ((playlist_list_t *)addr6(list->next_sequential))->playlist_start_sequential; } else { return ((playlist_list_t *)Addr6(first_playlist))->playlist_start_sequential; } case MODE_DIRRAND: // randomly choose files within 1 dir if (list->next_sequential) { return dirrand_new_list(list->next_sequential, 0); } else { return dirrand_new_list(first_playlist, 0); } case MODE_PLSTRAND: // seq within each dir, choose dirs randomly if (list->next_random == 0) { plstrand_randomize_incremental(simm_id_from_pointer(list)); } sdcc_bug_587536_workaround(list); return ((playlist_list_t *)Addr6(list->next_random))->playlist_start_sequential; case MODE_ALLRAND: // randomly choose files among all dirs return next_file_ptr(p, 0); default: break; } return 0;}simm_id prev_playlist_ptr(playlist_t *p){ playlist_list_t *list; list = Addr6(p->playlist); switch (play_mode) { case MODE_DIRONLY: // sequential within one directory case MODE_SEQNTIAL: // sequential among all directories if (list->prev_sequential) { return ((playlist_list_t *)addr6(list->prev_sequential))->playlist_start_sequential; } else { return ((playlist_list_t *)Addr6(last_playlist))->playlist_start_sequential; } case MODE_DIRRAND: // randomly choose files within 1 dir if (list->prev_sequential) { return dirrand_new_list(list->prev_sequential, 0); } else { return dirrand_new_list(last_playlist, 0); } case MODE_PLSTRAND: // seq within each dir, choose dirs randomly if (list->prev_random == 0) { plstrand_randomize_incremental(simm_id_from_pointer(list)); } sdcc_bug_587536_workaround(list); return ((playlist_list_t *)Addr6(list->prev_random))->playlist_start_sequential; case MODE_KEYRAND: // play all files sequentially until a key is pressed // no decision, must be here due to keypress case MODE_ALLRAND: // randomly choose files among all dirs return prev_file_ptr(p); default: break; } return 0;}unsigned longplaylist_to_state(playlist_t *p){ playlist_state_t state; playlist_list_t *list; if (play_mode == MODE_SEQNTIAL || play_mode == MODE_DIRONLY) { state.part.song_offset = 0; while (p->prev_sequential) { p = Addr7(p->prev_sequential); state.part.song_offset++; } } else { state.part.song_offset = 0xFFFF; } if (play_mode == MODE_SEQNTIAL || play_mode == MODE_DIRONLY || play_mode == MODE_DIRRAND) { state.part.list_offset = 0; list = Addr7(p->playlist); while (list->prev_sequential) { list = Addr7(list->prev_sequential); state.part.list_offset++; } } else { state.part.list_offset = 0xFFFF; } print("playlist state = "); print_hex32(state.whole); print_crlf(); return state.whole;}simm_idstate_to_playlist(unsigned long state_in){ playlist_state_t state; playlist_t *song; playlist_list_t *list; state.whole = state_in; list = Addr7(first_playlist); if (state.part.list_offset != 0xFFFF) { while (state.part.list_offset && list->next_sequential) { list = Addr7(list->next_sequential); state.part.list_offset--; } } song = Addr7(list->playlist_start_sequential); if (state.part.song_offset != 0xFFFF) { while (state.part.song_offset && song->next_sequential) { song = Addr7(song->next_sequential); state.part.song_offset--; } } return simm_id_from_pointer(song);}/*************************************************************************************//* Randomization code for MODE_DIRRAND (randomly choose files within 1 dir) *//*************************************************************************************/// Dir Rand mode is tricky to implement. Though the purpose is to// play all files in one directory in random order, the user can
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -