diff --git a/src/cargador.c b/src/cargador.c index de9968d..b0cf080 100644 --- a/src/cargador.c +++ b/src/cargador.c @@ -371,17 +371,27 @@ int load_z80(char *filename) { page=7; break; default: - page=11; + page=255; break; } - printf("Loading page %d of length %d\n",page,longitud); - if(longitud2==0xFFFF) // uncompressed raw data - retval=fread(snap->page[page],16384,1,fichero); + printf("128k: Loading page %d of length %d\n",page,longitud); + if (page==255) //Discard the page + { + if(longitud2==0xFFFF) // uncompressed raw data + retval=fread(memo,16384,1,fichero); + else + uncompress_z80(fichero,16384,memo); + } else - uncompress_z80(fichero,16384,snap->page[page]); + { + if(longitud2==0xFFFF) // uncompressed raw data + retval=fread(snap->page[page],16384,1,fichero); + else + uncompress_z80(fichero,16384,snap->page[page]); + } } - } else { + } else { //48k snapshot while(!feof(fichero)) { retval=fread(byte_read,3,1,fichero); if(feof(fichero)) @@ -398,17 +408,29 @@ int load_z80(char *filename) { page=2; break; default: - page=11; + page=255; break; } - if(longitud2==0xFFFF) // uncompressed raw data - retval=fread(snap->page[page],16384,1,fichero); + printf("48k: Loading page %d of length %d\n",page,longitud2); + if (page==255) //Discard the page. It should never happen + { + if(longitud2==0xFFFF) // uncompressed raw data + retval=fread(memo,16384,1,fichero); + else + uncompress_z80(fichero,16384,memo); + } else - uncompress_z80(fichero,16384,snap->page[page]); + { + if(longitud2==0xFFFF) // uncompressed raw data + retval=fread(snap->page[page],16384,1,fichero); + else + uncompress_z80(fichero,16384,snap->page[page]); + } } } } else { + printf("48k model: Loading page of old type z80\n"); if(compressed) { // 48k compressed z80 loader @@ -449,7 +471,7 @@ int load_sna(char *filename) { int addr,loop; tempo=(unsigned char *)malloc(49179); - tempo2=(unsigned char *)malloc(98308); + tempo2=(unsigned char *)malloc(16384*5+4); snap=(struct z80snapshot *)malloc(sizeof(struct z80snapshot)); //Some inits @@ -476,7 +498,7 @@ int load_sna(char *filename) { return -1; } - if (0==fread(tempo2,1,98308,fichero)) { + if (0==fread(tempo2,1,16384*5+4,fichero)) { printf("48K SNA\n"); type=0; } else { @@ -675,3 +697,198 @@ void load_snap(struct z80snapshot *snap) { break; } } + +int extract_screen_sna (char *screen, FILE * fichero) { + + unsigned char *tempo; + unsigned char *tempo2; + unsigned char type=0; + unsigned char v1; + + if(fichero==NULL) return -1; // error + + tempo=(unsigned char *)malloc(49179); + tempo2=(unsigned char *)malloc(16384*5+4); + + if (1!=fread(tempo,49179,1,fichero)) { + free(tempo); + free(tempo2); + return -1; + } + + if (0==fread(tempo2,1,16384*5+4,fichero)) { + printf("48K SNA\n"); + type=0; + } else { + printf("128K SNA\n"); + type=1; + } + + if (type==0) { //48k + + memcpy(screen,tempo+27,6912); + + } else { //128k + + v1=tempo2[2]; + //printf("v1= %d\n",(int) v1); + if ((v1&8)==0) memcpy(screen,tempo+27,6912); //screen in bank 5 + else //Screen in bank 7 + { + v1&=0x07; + if (v1==7) memcpy(screen,tempo+27+49152,6912); //screen in bank 7 paged-in + else + memcpy(screen,tempo2+4+16384*4,6912); //Screen in bank 7 not paged-in + } + } + + free(tempo); + free(tempo2); + return 0; +} + +int extract_screen_z80 (char *screen, FILE * fichero) { + + unsigned char tempo[30],tempo2[56],type,compressed,pager, byte_read[3]; + unsigned char *memo; + int longitud=0,longitud2,model_type; + + if(fichero==NULL) return -1; // error + + memo=(unsigned char *)malloc(49152); + + printf("Read Z80 file\n"); + + printf("Read header (first 30 bytes)\n"); + fread(tempo,1,30,fichero); + + if((tempo[6]==0)&&(tempo[7]==0)) { // extended Z80 + printf("It's an extended Z80 file\n"); + type=1; // new type + + fread(tempo2,1,2,fichero); // read the length of the extension + + longitud=((int)tempo2[0])+256*((int)tempo2[1]); + if(longitud>54) { + printf("Not suported Z80 file\n"); + free(memo); + return -3; // not a supported Z80 file + } + printf("Length: %d\n",longitud); + fread(tempo2+2,1,longitud,fichero); + + if(longitud==23) // z80 ver 2.01 + switch(tempo2[4]) { + case 0: + case 1: + model_type=0; // 48K + break; + case 3: + case 4: + model_type=1; // 128K + break; + default: + printf("Again not suported Z80 file\n"); + free(memo); + return -3; // not a supported Z80 file + break; + } + else // z80 ver 3.0x + switch(tempo2[4]) { + case 0: + case 1: + case 3: + model_type=0; // 48K + break; + case 4: + case 5: + case 6: + model_type=1; // 128K + break; + default: + free(memo); + return -3; // not a supported Z80 file + break; + } + } else { + printf("Old type z80\n"); + type=0; // old type + model_type=0; // 48k + } + + if(tempo[12]&32) + compressed=1; + else + compressed=0; + + if (type) pager=tempo2[5]; + + + if(type) { // extended z80 + if(model_type==1) { // 128K snapshot + + while(!feof(fichero)) { + fread(byte_read,3,1,fichero); + if(feof(fichero)) + break; + longitud2=((int)byte_read[0])+256*((int)byte_read[1]); + + printf("128k model: Loading page %d of length %d\n",byte_read[2]-3,longitud); + + if (((byte_read[2] == 8) && ((pager&8)==0))|| //Page 5 and no shadow screen + ((byte_read[2] == 10) && (pager&8))) //Page 7 and shadow screen + { + if(longitud2==0xFFFF) // uncompressed raw data + fread(memo,6912,1,fichero); + else + uncompress_z80(fichero,6912,memo); + memcpy(screen, memo,6912); + break; + } + if(longitud2==0xFFFF) longitud2 =16384; // uncompressed raw data + fread(memo,longitud2,1,fichero); + } + + } else { //48k snapshot + while(!feof(fichero)) { + fread(byte_read,3,1,fichero); + if(feof(fichero)) + break; + longitud2=((int)byte_read[0])+256*((int)byte_read[1]); + printf("48k model: Loading page of length %d\n",longitud2); + + if (byte_read[2] == 8) //Page 0 + { + if(longitud2==0xFFFF) // uncompressed raw data + fread(memo,6912,1,fichero); + else + uncompress_z80(fichero,6912,memo); + memcpy(screen, memo,6912); + break; + } + if(longitud2==0xFFFF) longitud2 =16384; // uncompressed raw data + fread(memo,longitud2,1,fichero); + } + } + } else { //Old type z80 + + printf("48k model: Loading page of old type z80\n"); + if(compressed) { + // 48k compressed z80 loader + + // we uncompress first the data + uncompress_z80(fichero,6912,memo); //uncompress only the screen + + memcpy(screen,memo,6912); + + } else { + // 48k uncompressed z80 loader + + fread(screen,6912,1,fichero); + } + + } + + free(memo); + return 0; // all right +} \ No newline at end of file diff --git a/src/cargador.h b/src/cargador.h index caa1544..114435f 100644 --- a/src/cargador.h +++ b/src/cargador.h @@ -29,7 +29,7 @@ struct z80snapshot { byte type; // bit 0/1: 48K/128K/+3 byte border; // border color byte pager; // content of pagination register in 128K mode - unsigned char page[12][16384]; + unsigned char page[8][16384]; //unsigned int found_pages; // bit=1: page exists. bit=0: page don't exists. unsigned char ay_regs[16]; unsigned char ay_latch; @@ -42,3 +42,5 @@ int load_z80(char *); int load_sna(char *); void load_snap(struct z80snapshot *); void uncompress_z80(FILE *,int,unsigned char *); +int extract_screen_sna (char *screen, FILE * fichero); +int extract_screen_z80 (char *screen, FILE * fichero); diff --git a/src/menu_sdl.c b/src/menu_sdl.c index 3845a2b..b8b4c83 100644 --- a/src/menu_sdl.c +++ b/src/menu_sdl.c @@ -43,6 +43,7 @@ #include "minizip/unzip.h" #include "tape_browser.h" +#include "cargador.h" #include "sound.h" @@ -514,27 +515,124 @@ void print_font(SDL_Surface *screen, int r, int g, int b, SDL_FreeSurface(font_surf); } -void draw_scr_file(int x,int y, char *filename) +int extract_screen(char* screen, const char* name) +{ + FILE *fichero; + char filename[MAX_PATH_LENGTH]; + char char_id[10]; + int retorno; + + if ((ext_matches(name, ".tap")||ext_matches(name, ".TAP"))) + { + sprintf(filename,"%s/%s",load_path_taps, name); + fichero=fopen(filename,"rb"); + if (!fichero) //Try in the tmp zip directory + { + sprintf(filename,"%s/%s",path_tmp, name); + fichero=fopen(filename,"rb"); + if (!fichero) return -1; + } + retorno = extract_screen_tap(screen, fichero); + fclose(fichero); + return retorno; + } + + if ((ext_matches(name, ".tzx")||ext_matches(name, ".TZX"))) + { + sprintf(filename,"%s/%s",load_path_taps, name); + fichero=fopen(filename,"rb"); + if (!fichero) //Try in the tmp zip directory + { + sprintf(filename,"%s/%s",path_tmp, name); + fichero=fopen(filename,"rb"); + if (!fichero) return -1; + } + fread(char_id,10,1,fichero); // read the (maybe) TZX header + if((strncmp(char_id,"ZXTape!",7)) || (char_id[7]!=0x1A) || (char_id[8]!=1)) + {fclose(fichero);retorno = -1;}; + retorno = extract_screen_tzx(screen, fichero); + fclose(fichero); + return retorno; + } + + if (ext_matches(name, ".z80")||ext_matches(name, ".Z80")||ext_matches(name, ".sna")||ext_matches(name, ".SNA")) + { + sprintf(filename,"%s/%s",load_path_snaps, name); + fichero=fopen(filename,"rb"); + if (!fichero) //Try in the tmp zip directory + { + sprintf(filename,"%s/%s",path_tmp, name); + fichero=fopen(filename,"rb"); + if (!fichero) return -1; + } + if (ext_matches(name, ".z80")||ext_matches(name, ".Z80")) retorno = extract_screen_z80(screen, fichero); + else retorno = extract_screen_sna(screen, fichero); + fclose(fichero); + return retorno; + } + + return -1; +} + +void draw_scr_file(int x,int y, const char *selected_file, int which) { FILE *fichero; char screen [6912]; unsigned int *p_translt, *p_translt2; unsigned char attribute, ink, paper, mask, octect; - int loop_x, loop_y,bucle,valor,*p ; + int loop_x, loop_y,bucle,valor,*p, length; unsigned char *address; - + char name[MAX_PATH_LENGTH]; + char filename[MAX_PATH_LENGTH]; + char *ptr; - if (filename==NULL) // Aborted + if (selected_file==NULL) // Aborted return; + + strcpy(name,selected_file); - if (!(ext_matches(filename, ".scr")||ext_matches(filename, ".SCR"))) return; + if ((ext_matches(name, ".zip")||ext_matches(name, ".ZIP"))) + { + //remove the zip extension + ptr = strrchr (name, '.'); + if (ptr) *ptr = 0; + } - fichero=fopen(filename,"rb"); + //remove the other extensions + ptr = strrchr (name, '.'); + if (ptr) *ptr = 0; + + //Always load from Default device + strcpy(filename,getenv("HOME")); + length=strlen(filename); + if ((length>0)&&(filename[length-1]!='/')) + strcat(filename,"/"); + if (which==0) strcat(filename, "scr/"); else strcat(filename, "scr2/"); + strcat(filename, name); + strcat(filename, ".scr"); + + if (which) //second SCR + { + fichero=fopen(filename,"rb"); - if (!fichero) return; + if (!fichero) return; + + if (fread(screen,1,6912,fichero)!=6912) {fclose(fichero);return;} + fclose(fichero); + } + else //first SCR + { + fichero=fopen(filename,"rb"); + + if (!fichero) + {if (extract_screen(screen, selected_file)) return;} + else + { + if (fread(screen,1,6912,fichero)!=6912) {fclose(fichero);return;} + fclose(fichero); + } + } - if (fread(screen,1,6912,fichero)!=6912) {fclose(fichero);return;} - fclose(fichero); p_translt = ordenador.translate; p_translt2 = ordenador.translate2; @@ -631,10 +729,7 @@ static void menu_draw(SDL_Surface *screen, menu_t *p_menu, int sel, int font_typ SDL_Rect r; int entries_visible = (p_menu->y2 - p_menu->y1-10/RATIO) / line_height - 1; const char *selected_file = NULL; - char filename[MAX_PATH_LENGTH]; - char name[MAX_PATH_LENGTH]; - char *ptr; - int i, y, length, max_string; + int i, y, max_string; if (font_type==FONT_ALT) y_start = p_menu->y1 + line_height+2/RATIO; else y_start = p_menu->y1 + line_height+4/RATIO; @@ -835,40 +930,8 @@ static void menu_draw(SDL_Surface *screen, menu_t *p_menu, int sel, int font_typ if ((!selected_file)||(selected_file[0] == '[')) return; //No dir - // Select after "/" - if (strrchr(selected_file, '/')) - strcpy(name, strrchr(selected_file, '/') + 1); - else strcpy(name,selected_file); - - if ((ext_matches(name, ".zip")||ext_matches(name, ".ZIP"))) - { - //remove the zip extension - ptr = strrchr (name, '.'); - if (ptr) *ptr = 0; - } - - //remove the other extensions - ptr = strrchr (name, '.'); - if (ptr) *ptr = 0; - - //Always load from Default device - strcpy(filename,getenv("HOME")); - length=strlen(filename); - if ((length>0)&&(filename[length-1]!='/')) - strcat(filename,"/"); - strcat(filename, "scr/"); - strcat(filename, name); - strcat(filename, ".scr"); - draw_scr_file(375,48, filename); - - strcpy(filename,getenv("HOME")); - length=strlen(filename); - if ((length>0)&&(filename[length-1]!='/')) - strcat(filename,"/"); - strcat(filename, "scr2/"); - strcat(filename, name); - strcat(filename, ".scr"); - draw_scr_file(375,260, filename); + draw_scr_file(375,48, selected_file,0); + draw_scr_file(375,260, selected_file,1); } } diff --git a/src/tape_browser.c b/src/tape_browser.c index 738020e..9471ec6 100644 --- a/src/tape_browser.c +++ b/src/tape_browser.c @@ -130,6 +130,7 @@ void create_browser_tzx (FILE * fichero) { { retval=fread (value, 1, longitud-1, fichero); if (retval!=(longitud-1)) {retorno=1;break;} + //if (longitud==6914) save_scr_browser(value+1); } break; default: //Custom data @@ -395,6 +396,7 @@ void create_browser_tap (FILE * fichero) { { retval=fread (value, 1, longitud-1, fichero); if (retval!=(longitud-1)) {retorno=1;break;} + //if (longitud==6914) save_scr_browser(value+1); } break; default: //Custom data @@ -546,4 +548,347 @@ void free_browser() block_select_list[bucle]=NULL; } -} \ No newline at end of file +} + +/* +void save_scr_browser(unsigned char* zx_screen) +{ + //const char *tape = ordenador.last_selected_file; + const char *tape =ordenador.current_tap; + char *ptr; + FILE *fichero; + char db[MAX_PATH_LENGTH]; + char fb[81]; + int retorno,retval; + + + // Name (for saves) - TO CHECK + if (tape && strrchr(tape, '/')) + strncpy(fb, strrchr(tape, '/') + 1, 80); + else + strcpy(fb, "unknown"); + + //remove the extension + ptr = strrchr (fb, '.'); + if (ptr) *ptr = 0; + + + // Save SCR 1 file + snprintf(db, MAX_PATH_LENGTH-1, "%s/%s.scr", path_scr1, fb); + + + fichero=fopen(db,"rb"); + + if(fichero!=NULL) + { + fclose(fichero); + return; // file already exists + } + + fichero=fopen(db,"wb"); // create for write + + if(fichero==NULL) + retorno=-1; + else { + retval=fwrite(zx_screen,6912,1,fichero); // save screen + //if (ordenador.ulaplus!=0) { + //retval=fwrite(ordenador.ulaplus_palete,64,1,fichero); // save ULAPlus palete + //} + fclose(fichero); + retorno=0; + } + + switch(retorno) { + case 0: + msgInfo("Screen saved",3000,NULL); + break; + case -1: + msgInfo("Can't create screen file",3000,NULL); + break; + default: + break; + } + return; +} +*/ + +int extract_screen_tap (char *screen, FILE * fichero) { + + unsigned int longitud; + unsigned char value[65536], empty, flag_byte; + int retval, retorno; + + if (fichero == NULL) return -1; + + empty=file_empty(fichero); + + if (empty) return -1; + + flag_byte=0; + retorno=0; + do { + 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 + if (longitud!=19) + { + 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;} + } + break; + case 0xFF: //data + if (longitud>1) + { + retval=fread (value, 1, longitud-1, fichero); + if (retval!=(longitud-1)) {retorno=1;break;} + if (longitud==6914) {memcpy(screen, value+1, 6912);rewind_tape (fichero,1);return 0;} + } + break; + default: //Custom data + if (longitud>1) + { + retval=fread (value, 1, longitud-1, fichero); + if (retval!=(longitud-1)) {retorno=1;break;} + if (longitud==6914) {memcpy(screen, value+1, 6912);rewind_tape (fichero,1);return 0;} + } + break; + } + } while ((!feof(fichero))&&(retorno==0)); + +rewind_tape (fichero,1); +return -1; +} + +int extract_screen_tzx (char *screen, FILE * fichero) +{ + + unsigned int longitud, bucle, byte_position, retorno; + unsigned char value[65536], empty, blockid, pause[2], flag_byte; + char block_jump[2]; + int retval, retval2; + //int found_screen; + + longitud =0; + pause[0]=pause[1]=0; + + blockid=0; + flag_byte=0; + //found_screen=0; + + if (fichero == NULL) return -1; + + empty=file_empty(fichero); + + if (empty) return -1; + + retorno=0; + do { + byte_position=ftell(fichero); + retval=fread (&blockid, 1, 1, fichero); //Read id block + if (retval!=1) {retorno=1;break;} + + //printf("TZX browser: %X en %d\n",blockid, byte_position+1); + + switch(blockid) { + case 0x10: // classic tape block + 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;} + longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]); + retval=fread (&flag_byte, 1, 1, fichero); + if (retval!=1) {retorno=1;break;} + switch(flag_byte) + { + case 0x00: //header + if (longitud!=19) + { + 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;} + } + break; + case 0xFF: //data + if (longitud>1) + { + retval=fread (value, 1, longitud-1, fichero); + if (retval!=(longitud-1)) {retorno=1;break;} + if (longitud==6914) {memcpy(screen, value+1, 6912);rewind_tape (fichero,1);return 0;} + } + break; + default: //Custom data + if (longitud>1) + { + retval=fread (value, 1, longitud-1, fichero); + if (retval!=(longitud-1)) {retorno=1;break;} + if (longitud==6914) {memcpy(screen, value+1, 6912);rewind_tape (fichero,1);return 0;} + } + break; + } + break; + + case 0x11: // turbo + fread(value,1,0x0F, fichero); + retval=fread (value, 1,3 ,fichero); // read length of current block + if (retval!=3) {retorno=1;break;} + longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1])+ 65536 * ((unsigned int) value[2]); + if (longitud< 65536) + {retval=fread (value, 1, longitud, fichero); if (retval!=longitud) {retorno=1;break;}} + else + for(bucle=0;bucle