diff --git a/src/emulator.c b/src/emulator.c index ed4dc97..42e1210 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -38,6 +38,7 @@ #include "tape.h" #include "microdrive.h" #include "menu_sdl.h" +#include "tape_browser.h" #include @@ -1615,5 +1616,7 @@ int main(int argc,char *argv[]) { fatUnmount(0); #endif + free_browser(); + return 0; } diff --git a/src/gui_sdl.c b/src/gui_sdl.c index 1942cc1..721f0c3 100644 --- a/src/gui_sdl.c +++ b/src/gui_sdl.c @@ -234,17 +234,19 @@ static void tape_browser() { unsigned int tape_position, block_n_int; const char *row_selected; - char block_n[4]; + char block_n[5]; + + if (browser_list[0]==NULL) {msgInfo("No tape inserted",3000,NULL);return;} row_selected = menu_select_browser(ordenador.tape_position); if (row_selected==NULL) // Aborted return; - if (row_selected[0]==']') strncpy(block_n, row_selected+1,3); - else strncpy(block_n, row_selected,3); + if (row_selected[0]==']') strncpy(block_n, row_selected+1,4); + else strncpy(block_n, row_selected,4); - block_n[3]=0; + block_n[4]=0; block_n_int=atoi(block_n); diff --git a/src/menu_sdl.c b/src/menu_sdl.c index 791094f..8c1effa 100644 --- a/src/menu_sdl.c +++ b/src/menu_sdl.c @@ -1294,24 +1294,43 @@ const char **get_file_list_browser(unsigned int tape_pos, unsigned int *block_po unsigned int loop; char **browser_list_menu; + *block_pos=0; + browser_list_menu = (char**)malloc((MAX_BROWSER_ITEM+1) * sizeof(char*)); browser_list_menu[0] = NULL; for(loop=0;browser_list[loop]!=NULL;loop++) { - browser_list_menu[loop]=malloc(24+32+8); + browser_list_menu[loop]=malloc(24+36+9); if (browser_list[loop]->position==tape_pos) { - sprintf(browser_list_menu[loop],"]%03d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info); + sprintf(browser_list_menu[loop],"]%04d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info); *block_pos=loop; } else - sprintf(browser_list_menu[loop],"%03d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info); + sprintf(browser_list_menu[loop],"%04d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info); } browser_list_menu[loop]=NULL; return (const char **) browser_list_menu; } +const char **get_file_list_select_block() +{ + unsigned int loop; + char **block_list_menu; + + block_list_menu = (char**)malloc((MAX_SELECT_ITEM+1) * sizeof(char*)); + block_list_menu[0] = NULL; + + for(loop=0;block_select_list[loop]!=NULL;loop++) + { + block_list_menu[loop]=malloc(32); + sprintf(block_list_menu[loop],"%02d %s",loop, block_select_list[loop]->info); + } + block_list_menu[loop]=NULL; + return (const char **) block_list_menu; +} + static const char *menu_select_file_internal(char *dir_path, int x, int y, int x2, int y2, const char *selected_file, int draw_scr, unsigned int tape_pos) { @@ -1326,12 +1345,15 @@ static const char *menu_select_file_internal(char *dir_path, char buf[64]; unsigned int block_pos; - if (strcmp(dir_path,"browser")) file_list = get_file_list(dir_path); else file_list = get_file_list_browser(tape_pos, &block_pos); + if (!strcmp(dir_path,"browser")) file_list = get_file_list_browser(tape_pos, &block_pos); + else if (!strcmp(dir_path,"select_block")) file_list = get_file_list_select_block(); + else file_list = get_file_list(dir_path); if (file_list == NULL) return NULL; - if (!strcmp(dir_path,"browser")) opt = menu_select_sized("Select block", file_list, NULL, block_pos, x, y, x2, y2, NULL, NULL ,16, draw_scr); + if (!strcmp(dir_path,"browser")) opt = menu_select_sized("Select block", file_list, NULL, block_pos, x, y, x2, y2, NULL, NULL ,16, 0); + else if (!strcmp(dir_path,"select_block")) opt = menu_select_sized("Select program", file_list, NULL, 0, x, y, x2, y2, NULL, NULL ,16, 0); else if (selected_file) { ptr_selected_file= strrchr(selected_file,'/'); @@ -1354,7 +1376,7 @@ static const char *menu_select_file_internal(char *dir_path, if (!sel) return NULL; - if (!strcmp(dir_path,"browser")) return sel; + if (!strcmp(dir_path,"browser")||!strcmp(dir_path,"select_block")) return sel; if (!strcmp(sel,"[..]")) //selected "[..]" { @@ -1427,6 +1449,13 @@ const char *menu_select_browser(unsigned int tape_pos) 0, 20/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 20/RATIO, NULL, 0, tape_pos); } +const char *menu_select_tape_block() +{ + SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0)); + return menu_select_file_internal("select_block", + 0, 20/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 20/RATIO, NULL, 0, 0); +} + static TTF_Font *read_font(const char *path, int font_size) { diff --git a/src/menu_sdl.h b/src/menu_sdl.h index d68c0b3..326110c 100644 --- a/src/menu_sdl.h +++ b/src/menu_sdl.h @@ -74,4 +74,6 @@ int ask_value_sdl(int *final_value,int y_coord,int max_value); int ask_filename_sdl(char *nombre_final,int y_coord,char *extension, char *path, char *name); +const char *menu_select_tape_block(); + #endif /* !__MENU_H__ */ diff --git a/src/tape.c b/src/tape.c index d7dfea8..61e11ab 100644 --- a/src/tape.c +++ b/src/tape.c @@ -23,6 +23,7 @@ #include "emulator.h" #include "menus.h" #include "tape.h" +#include "tape_browser.h" #ifdef DEBUG extern FILE *fdebug; @@ -204,7 +205,7 @@ inline void tape_read_tap (FILE * fichero, int tstados) { inline void tape_read_tzx (FILE * fichero, int tstados) { static unsigned char value, value2,value3,value4,done; - static unsigned int bucle,bucle2; + static unsigned int bucle,bucle2, byte_position; int retval; if (fichero == NULL) @@ -221,8 +222,8 @@ inline void tape_read_tzx (FILE * fichero, int tstados) { if (ordenador.tape_current_mode == TAP_TRASH) { // initialize a new block done = 0; - ordenador.tape_position=ftell(fichero); do { + ordenador.tape_position=ftell(fichero); retval=fread(&value,1,1,fichero); // read block ID printf("TZX:ID_normal: %X en %ld\n",value,ftell(fichero)); if(feof(fichero)) @@ -438,11 +439,17 @@ inline void tape_read_tzx (FILE * fichero, int tstados) { break; case 0x28: // select block - retval=fread(&value2,1,1,fichero); - retval=fread(&value3,1,1,fichero); - bucle2 = ((unsigned int) value2) + 256 * ((unsigned int) value3); - for(bucle=0;bucleposition=byte_position; - strcpy(browser_list[block_number]->info, " "); + strcpy(browser_list[block_number]->info, " "); - printf("TZX: browser: %X en %d\n",blockid, byte_position); + printf("TZX browser: %X en %d\n",blockid, byte_position); switch(blockid) { case 0x10: // classic tape block - strcpy(browser_list[block_number]->block_type,"Standard speed data"); + strcpy(browser_list[block_number]->block_type,"Standard Speed Data"); retval=fread (pause, 1, 2, fichero); //pause lenght retval2=fread (value, 1, 2, fichero); // read length of current block if ((retval!=2)||(retval2!=2)) {retorno=1;break;} @@ -93,6 +94,17 @@ void browser_tzx (FILE * fichero) { switch(flag_byte) { case 0x00: //header + if (longitud!=19) + { + sprintf(browser_list[block_number]->info,"Custom Data: %d bytes", longitud); + if (longitud>1) + { + retval=fread (value, 1, longitud-1, fichero); + if (retval!=(longitud-1)) {retorno=1;break;} + } + } + else + { retval=fread (value, 1, 18, fichero); if (retval!=18) {retorno=1;break;} value[11]=0; @@ -111,10 +123,11 @@ void browser_tzx (FILE * fichero) { case 0X03: sprintf(browser_list[block_number]->info,"Code: %s", value+1); break; - default: //?? - strcpy(browser_list[block_number]->info,"???"); + default: //Custom header + sprintf(browser_list[block_number]->info,"Custom header: %s", value+1); break; } + } break; case 0xFF: //data sprintf(browser_list[block_number]->info,"Standard Data: %d bytes", longitud); @@ -135,7 +148,7 @@ void browser_tzx (FILE * fichero) { } break; case 0x11: // turbo - strcpy(browser_list[block_number]->block_type,"Turbo speed data "); + strcpy(browser_list[block_number]->block_type,"Turbo Speed Data "); retval=fread(value,1,0x0F, fichero); retval=fread (value, 1,3 ,fichero); // read length of current block if (retval!=3) {retorno=1;break;} @@ -146,11 +159,12 @@ void browser_tzx (FILE * fichero) { break; case 0x12: // pure tone - strcpy(browser_list[block_number]->block_type,"Pure tone "); + strcpy(browser_list[block_number]->block_type,"Pure Tone "); retval=fread(value,1,4,fichero); if (retval!=4) {retorno=1;break;} + len = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]); longitud = ((unsigned int) value[2]) + 256 * ((unsigned int) value[3]); - sprintf(browser_list[block_number]->info,"%d pulses", longitud); + sprintf(browser_list[block_number]->info,"%d pulses of %d Ts", longitud, len); break; case 0x13: // multiple pulses @@ -165,7 +179,7 @@ void browser_tzx (FILE * fichero) { break; case 0x14: // Pure data - strcpy(browser_list[block_number]->block_type,"Pure data "); + strcpy(browser_list[block_number]->block_type,"Pure Data "); retval=fread(value,1,0x07, fichero); retval=fread (value, 1, 3, fichero); // read length of current block if (retval!=3) {retorno=1;break;} @@ -179,7 +193,7 @@ void browser_tzx (FILE * fichero) { retval=fread(value,1,2,fichero); if (retval!=2) {retorno=1;break;} longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]); - if (longitud==0) strcpy(browser_list[block_number]->block_type,"Stop tape "); + if (longitud==0) strcpy(browser_list[block_number]->block_type,"Stop the Tape "); else { strcpy(browser_list[block_number]->block_type,"Pause: "); @@ -193,7 +207,7 @@ void browser_tzx (FILE * fichero) { if (retval!=1) {retorno=1;break;} len = (unsigned int) value[0]; retval=fread(value,1,len,fichero); - if (len>31) len=31; + if (len>35) len=35; value[len]=0; strcpy(browser_list[block_number]->info,value); break; @@ -212,7 +226,7 @@ void browser_tzx (FILE * fichero) { break; case 0x28: // select block - strcpy(browser_list[block_number]->block_type,"Select block "); + strcpy(browser_list[block_number]->block_type,"Select "); retval=fread(value,1,2,fichero); if (retval!=2) {retorno=1;break;} len = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]); @@ -226,13 +240,13 @@ void browser_tzx (FILE * fichero) { break; case 0x30: // text description - strcpy(browser_list[block_number]->block_type,"Text: "); + strcpy(browser_list[block_number]->block_type,"Text description: "); retval=fread(value,1,1,fichero); // length if (retval!=1) {retorno=1;break;} len = (unsigned int) value[0] ; retval=fread(value,1,len,fichero); if (retval!=len) {retorno=1;break;} - if (len>31) len=31; + if (len>35) len=35; value[len]=0; for(bucle=0;bucleblock_type,"Show text: "); + strcpy(browser_list[block_number]->block_type,"Show message: "); retval=fread(value,1,1,fichero); //Time lengt if (retval!=1) {retorno=1;break;} retval=fread(value,1,1,fichero); // length @@ -248,7 +262,7 @@ void browser_tzx (FILE * fichero) { len = (unsigned int) value[0]; retval=fread(value,1,len,fichero); if (retval!=len) {retorno=1;break;} - if (len>31) len=31; + if (len>35) len=35; value[len]=0; for(bucle=0;bucleblock_type,"Archive info: "); + strcpy(browser_list[block_number]->block_type,"Archive info "); retval=fread(value,1,2,fichero); // length if (retval!=2) {retorno=1;break;} len = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]); @@ -264,7 +278,7 @@ void browser_tzx (FILE * fichero) { break; case 0x33: // hardware info - strcpy(browser_list[block_number]->block_type,"Hardware info: "); + strcpy(browser_list[block_number]->block_type,"Hardware info "); retval=fread(value,1,1,fichero); if (retval!=1) {retorno=1;break;} len = (unsigned int) value[0] *3; @@ -272,12 +286,12 @@ void browser_tzx (FILE * fichero) { break; case 0x34: // emulation info - strcpy(browser_list[block_number]->block_type,"Emulation info: "); + strcpy(browser_list[block_number]->block_type,"Emulation info "); retval=fread(value,1,8,fichero); break; case 0x35: // custom info - strcpy(browser_list[block_number]->block_type,"Custom info: "); + strcpy(browser_list[block_number]->block_type,"Custom info "); retval=fread(value,1,16,fichero); retval=fread(value,1,4,fichero); if (retval!=4) {retorno=1;break;} @@ -334,20 +348,31 @@ void browser_tap (FILE * fichero) { do { byte_position=ftell(fichero); browser_list[block_number]=(struct browser *)malloc(sizeof(struct browser)); - //if (browser_list[block_number]==NULL) retorno=1; browser_list[block_number]->position=byte_position; - printf("TAP: browser: %X en %d\n",10, byte_position); - strcpy(browser_list[block_number]->block_type,"Standard speed data"); + strcpy(browser_list[block_number]->info, " "); + strcpy(browser_list[block_number]->block_type,"Standard Speed Data"); retval=fread (value, 1, 2, fichero); // read length of current block if (retval!=2) {retorno=1;break;} longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]); retval=fread (&flag_byte, 1, 1, fichero); if (retval!=1) {retorno=1;break;} + printf("TAP browser: flag byte %X en %ld\n",flag_byte, ftell(fichero)); switch(flag_byte) { case 0x00: //header - retval=fread (value, 1, 18, fichero); - if (retval!=18) {retorno=1;break;} + if (longitud!=19) + { + sprintf(browser_list[block_number]->info,"Custom Data: %d bytes", longitud); + if (longitud>1) + { + retval=fread (value, 1, longitud-1, fichero); + if (retval!=(longitud-1)) {retorno=1;break;} + } + } + else + { + retval=fread (value, 1, 18, fichero); + if (retval!=18) {retorno=1;break;} value[11]=0; for(bucle=1;bucle<11;bucle++) if (value[bucle]<' ') value[bucle]='?'; //not printable character @@ -364,13 +389,14 @@ void browser_tap (FILE * fichero) { case 0X03: sprintf(browser_list[block_number]->info,"Code: %s", value+1); break; - default: //?? - strcpy(browser_list[block_number]->info,"???"); + default: //Custom header + sprintf(browser_list[block_number]->info,"Custom header: %s", value+1); break; } + } break; case 0xFF: //data - sprintf(browser_list[block_number]->info,"Standard Data: %d bytes", longitud-2); + sprintf(browser_list[block_number]->info,"Standard Data: %d bytes", longitud); if (longitud>1) { retval=fread (value, 1, longitud-1, fichero); @@ -378,7 +404,7 @@ void browser_tap (FILE * fichero) { } break; default: //Custom data - sprintf(browser_list[block_number]->info,"Custom Data: %d bytes", longitud-2); + sprintf(browser_list[block_number]->info,"Custom Data: %d bytes", longitud); if (longitud>1) { retval=fread (value, 1, longitud-1, fichero); @@ -392,3 +418,109 @@ void browser_tap (FILE * fichero) { rewind_tape (fichero,1); browser_list[block_number]=NULL; } + +int select_block(FILE * fichero) +{ + unsigned int longitud, bucle, byte_position, block_number,nblocks,offset, blk_sel_pos; + unsigned char value[64], len_text; + int retval; + + block_number=0; + + //Free the block list + for(bucle=0; ((block_select_list[bucle]!=NULL)&&(bucleposition!=byte_position)); + blk_sel_pos++); + + if (browser_list[blk_sel_pos]->position!=byte_position) return -1; + + retval=fread(value,1,3,fichero); + if (retval!=3) {return -1;} + longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]); + nblocks=value[2]; + + if (nblocks>MAX_SELECT_ITEM) {return -1;} + + for(block_number=0;block_number64) return -1; + retval=fread (value, 1, len_text, fichero); //Read text + if (retval!=len_text) return -1; + if (len_text>31) len_text=31; + value[len_text]=0; + + block_select_list[block_number]=(struct tape_select *)malloc(sizeof(struct tape_select)); + block_select_list[block_number]->offset = offset; + strcpy(block_select_list[block_number]->info, value); + } + + block_select_list[block_number]=NULL; + if (feof(fichero)) return -1; + + unsigned int tape_position, block_n_int; + const char *row_selected; + char block_n[3]; + + row_selected = menu_select_tape_block(); + + if (row_selected==NULL) // Aborted + return -1; + + strncpy(block_n, row_selected,2); + + block_n[2]=0; + + block_n_int=atoi(block_n); + + if ((block_n_int<0)||(block_n_int >(MAX_SELECT_ITEM-1))) return -1; + + if ((block_select_list[block_n_int]->offset+blk_sel_pos) > (MAX_BROWSER_ITEM-1)) return -1; + + tape_position=browser_list[block_select_list[block_n_int]->offset+blk_sel_pos]->position; + + ordenador.tape_current_bit=0; + ordenador.tape_current_mode=TAP_TRASH; + ordenador.next_block= NOBLOCK; + + fseek(ordenador.tap_file, tape_position, SEEK_SET); + ordenador.tape_position = tape_position; + free((void*)row_selected); + + return 0; +} + +void free_browser() +{ + unsigned int bucle; + + //Free the browser list + for(bucle=0; ((browser_list[bucle]!=NULL)&&(bucle