static void show_file_error( FILE *stream ) { if( feof( stream ) ) Aprint( "Unexpected end of file during I/O operation, file is probably corrupt" ); else Aprint( "I/O error reading or writing a character" ); }
/* Opens a DCM file and decodes it to a temporary file, then returns the file handle for the temporary file and its name. */ FILE *opendcm( int diskno, const char *infilename, char *outfilename ) { FILE *infile, *outfile; FILE *file = NULL; char *curptr = outfilename; strcpy(curptr,"TMP_XXXXXX\0"); outfile = fdopen(mkstemp(curptr), "wb"); if( !outfile ){ Aprint("mkstemp failed\n"); return NULL; } infile = fopen( infilename, "rb" ); if( !infile ) { fclose( outfile ); } else { if( dcmtoatr( infile, outfile, infilename, outfilename ) != 0 ) { fflush( outfile ); fclose( outfile ); file = fopen(outfilename, "rb"); } } if(!file) { Aprint( "Removing temporary file %s", outfilename ); remove( outfilename ); } return file; }
/* added for Atari800, by perrym*/ void ATARI_NTSC_DEFAULTS_Initialise(int *argc, char *argv[], atari_ntsc_setup_t *atari_ntsc_setup) { int i, j; /* Adjust default values here */ atari_ntsc_setup->sharpness = -0.5; atari_ntsc_setup->saturation = -0.1; atari_ntsc_setup->gamma_adj = -0.25; atari_ntsc_setup->burst_phase = -0.60; atari_ntsc_setup->saturation_ramp = 0.25; for (i = j = 1; i < *argc; i++) { if (strcmp(argv[i], "-ntsc_hue") == 0) { atari_ntsc_setup->hue = atof(argv[++i]); }else if (strcmp(argv[i], "-ntsc_sat") == 0){ atari_ntsc_setup->saturation = atof(argv[++i]); }else if (strcmp(argv[i], "-ntsc_cont") == 0){ atari_ntsc_setup->contrast = atof(argv[++i]); }else if (strcmp(argv[i], "-ntsc_bright") == 0){ atari_ntsc_setup->brightness = atof(argv[++i]); }else if (strcmp(argv[i], "-ntsc_sharp") == 0){ atari_ntsc_setup->sharpness = atof(argv[++i]); }else if (strcmp(argv[i], "-ntsc_burst") == 0){ atari_ntsc_setup->burst_phase = atof(argv[++i]); }else if (strcmp(argv[i], "-ntsc_gauss") == 0){ atari_ntsc_setup->gaussian_factor = atof(argv[++i]); }else if (strcmp(argv[i], "-ntsc_gamma") == 0){ atari_ntsc_setup->gamma_adj = atof(argv[++i]); }else if (strcmp(argv[i], "-ntsc_ramp") == 0){ atari_ntsc_setup->saturation_ramp = atof(argv[++i]); } else { if (strcmp(argv[i], "-help") == 0) { Aprint("\t-ntsc_hue <n> Set NTSC hue -1..1 (default %.2g)",atari_ntsc_setup->hue); Aprint("\t-ntsc_sat <n> Set NTSC saturation (default %.2g)",atari_ntsc_setup->saturation); Aprint("\t-ntsc_cont <n> Set NTSC contrast (default %.2g)",atari_ntsc_setup->contrast); Aprint("\t-ntsc_bright <n> Set NTSC brightness (default %.2g)",atari_ntsc_setup->brightness); Aprint("\t-ntsc_sharp <n> Set NTSC sharpness (default %.2g)",atari_ntsc_setup->sharpness); Aprint("\t-ntsc_burst <n> Set NTSC burst phase -1..1 (artif colours)(def: %.2g)",atari_ntsc_setup->burst_phase); Aprint("\t-ntsc_gauss <n> Set NTSC Gaussian factor (default %.2g)",atari_ntsc_setup->gaussian_factor); Aprint("\t-ntsc_gamma <n> Set NTSC gamma adjustment (default %.2g)",atari_ntsc_setup->gamma_adj); Aprint("\t-ntsc_ramp <n> Set NTSC saturation ramp factor (default %.2g)",atari_ntsc_setup->saturation_ramp); } argv[j++] = argv[i]; } } *argc = j; }
void Palette_SetVideoSystem(int mode) { if (mode == TV_NTSC) { colortable = colortable_ntsc; color_settings = &color_settings_ntsc; } else if (mode == TV_PAL) { colortable = colortable_pal; color_settings = &color_settings_pal; } else { Atari800_Exit(FALSE); Aprint("Interal error: Invalid tv_mode\n"); exit(1); } }
void atari_ntsc_init( atari_ntsc_t* emu, atari_ntsc_setup_t const* setup ) { /* init pixel renderer */ int entry; float burst_phase = (setup->burst_phase) * pi; ntsc_to_rgb_t ntsc; ntsc_to_rgb_init( &ntsc, setup, setup->hue * pi - burst_phase ); for ( entry = 0; entry < atari_ntsc_color_count; entry++ ) { /*NTSC PHASE CONSTANTS.*/ float ntsc_phase_constant[16]={0,2.27,1.87,1.62, 1.22,0.62,-0.31,-0.855, -1.18,-1.43,-1.63,-1.93, -2.38,-3.43,2.52,2.07}; /*NTSC luma multipliers from gtia.pdf*/ float luma_mult[16]={ 0.6941, 0.7091, 0.7241, 0.7401, 0.7560, 0.7741, 0.7931, 0.8121, 0.8260, 0.8470, 0.8700, 0.8930, 0.9160, 0.9420, 0.9690, 1.0000}; /* calculate yiq for color entry */ int color = entry >> 4; float angle = burst_phase + ntsc_phase_constant[color]; float lumafactor = ( luma_mult[ entry & 0x0f] - luma_mult[0] )/( luma_mult[15] - luma_mult[0] ); float adj_lumafactor = pow(lumafactor, 1 +setup->gamma_adj); float y = adj_lumafactor * rgb_unit; float base_saturation = (color ? rgb_unit * 0.35f: 0.0f); float saturation_ramp = setup->saturation_ramp; float saturation = base_saturation * ( 1 - saturation_ramp*lumafactor ); float i = sin( angle ) * saturation; float q = cos( angle ) * saturation; ntsc_rgb_t* out = emu->table [entry]; y = y * ntsc.contrast + ntsc.brightness; /* generate at four alignments with respect to output */ ntsc.composite [composite_border + 0] = i + y; ntsc.composite [composite_border + 1] = q + y; out = gen_pixel( &ntsc, 0, 0, out ); ntsc.composite [composite_border + 0] = 0; ntsc.composite [composite_border + 1] = 0; ntsc.composite [composite_border + 2] = i - y; ntsc.composite [composite_border + 3] = q - y; out = gen_pixel( &ntsc, 2, 2, out ); ntsc.composite [composite_border + 2] = 0; ntsc.composite [composite_border + 3] = 0; ntsc.composite [composite_border + 4] = i + y; ntsc.composite [composite_border + 5] = q + y; out = gen_pixel( &ntsc, 4, 4, out ); ntsc.composite [composite_border + 4] = 0; ntsc.composite [composite_border + 5] = 0; ntsc.composite [composite_border + 6] = i - y; ntsc.composite [composite_border + 7] = q - y; out = gen_pixel( &ntsc, 6, 6, out ); ntsc.composite [composite_border + 6] = 0; ntsc.composite [composite_border + 7] = 0; /* correct roundoff errors that would cause vertical bands in solid areas */ { float r = y + i * ntsc.to_rgb [0] + q * ntsc.to_rgb [1]; float g = y + i * ntsc.to_rgb [2] + q * ntsc.to_rgb [3]; float b = y + i * ntsc.to_rgb [4] + q * ntsc.to_rgb [5]; ntsc_rgb_t correct = MAKE_KRGB( (int) r, (int) g, (int) b ) + MAKE_KMASK( 0x100 ); int i; out = emu->table [entry]; for ( i = 0; i < rgb_kernel_size / 2; i++ ) { /* sum as would occur when outputting run of pixels using same color, but don't sum first kernel; the difference between this and the correct color is what the first kernel's entry should be */ ntsc_rgb_t sum = out [(i+12)%14+14]+out[(i+10)%14+28]+out[(i+8)%14+42]+ out[i+7]+out [ i+ 5 +14]+out[ i+ 3 +28]+out[ i+1 +42]; out [i] = correct - sum; } } } Aprint("atari_ntsc_init(): sharpness:%f saturation:%f brightness:%f contrast:%f gaussian_factor:%f burst_phase:%f, hue:%f gamma_adj:%f saturation_ramp:%f\n",setup->sharpness,setup->saturation,setup->brightness,setup->contrast,setup->gaussian_factor,setup->burst_phase,setup->hue,setup->gamma_adj,setup->saturation_ramp); }
void Atari_Initialise(int *argc, char *argv[]) { int i; int j; int use_lpt1=0,use_lpt2=0,use_lpt3=0; int help_only = FALSE; for (i = j = 1; i < *argc; i++) { if (strcmp(argv[i], "-interlace") == 0) { ypos_inc = 2; vga_ptr_inc = 320 + 320; scr_ptr_inc = ATARI_WIDTH + ATARI_WIDTH; } else if (strcmp(argv[i], "-LPTjoy1") == 0) use_lpt1=test_LPTjoy(1,NULL); else if (strcmp(argv[i], "-LPTjoy2") == 0) use_lpt2=test_LPTjoy(2,NULL); else if (strcmp(argv[i], "-LPTjoy3") == 0) use_lpt3=test_LPTjoy(3,NULL); else if (strcmp(argv[i], "-joyswap") == 0) joyswap = TRUE; else if (strcmp(argv[i], "-video") == 0) { i++; video_mode=atoi(argv[i]); if (video_mode<0 || video_mode>3) { Aprint("Invalid video mode, using default."); video_mode=0; } } else if (strcmp(argv[i],"-novesa") == 0) { use_vesa=FALSE; } else if (strcmp(argv[i],"-vretrace") == 0) { use_vret=TRUE; } else if (strcmp(argv[i],"-keyboard") == 0) { i++; if (strcmp(argv[i],"0") == 0) PC_keyboard = TRUE; else PC_keyboard = FALSE; } else { if (strcmp(argv[i], "-help") == 0) { help_only = TRUE; Aprint("\t-interlace Generate screen with interlace"); Aprint("\t-LPTjoy1 Read joystick connected to LPT1"); Aprint("\t-LPTjoy2 Read joystick connected to LPT2"); Aprint("\t-LPTjoy3 Read joystick connected to LPT3"); Aprint("\t-joyswap Swap joysticks"); Aprint("\t-video x Set video mode:"); Aprint("\t\t0 - 320x200\n\t\t1 - 320x240"); Aprint("\t\t2 - 320x240, interlaced with black lines"); Aprint("\t\t3 - 320x240, interlaced with darker lines (slower!)"); Aprint("\t-novesa Do not use vesa2 videomodes"); Aprint("\t-vretrace Use vertical retrace control"); Aprint("\t-keyboard 0 PC keyboard layout"); Aprint("\t-keyboard 1 Atari keyboard layout"); } argv[j++] = argv[i]; } } *argc = j; #ifdef SOUND /* initialise sound routines */ Sound_Initialise(argc, argv); #endif if (help_only) return; /* check if joystick is connected */ printf("Joystick is checked...\n"); fflush(stdout); outportb(0x201, 0xff); usleep(100000UL); joy_in = ((inportb(0x201) & 3) == 0); if (joy_in) joystick0(&js0_centre_x, &js0_centre_y); if (! joy_in) Aprint("Sorry, I see no joystick. Use numeric pad"); /*find number of VESA2 video mode*/ if (use_vesa) { switch(video_mode) { case 0: use_vesa=VESA_getmode(320,200,&vesa_mode,&vesa_memptr,&vesa_linelenght,&vesa_memsize); break; case 1: use_vesa=VESA_getmode(320,240,&vesa_mode,&vesa_memptr,&vesa_linelenght,&vesa_memsize); break; case 2: case 3: use_vesa=VESA_getmode(320,480,&vesa_mode,&vesa_memptr,&vesa_linelenght,&vesa_memsize); break; } } /* setup joystick */ stick0 = stick1 = stick2 = stick3 = STICK_CENTRE; trig0 = trig1 = trig2 = trig3 = 1; /* for compatibility with older versions' command line parameters */ if (use_lpt3) { for (i=3;i>0;i--) joytypes[i]=joytypes[i-1]; /*shift joystick types up*/ joytypes[0]=joy_lpt3; /*joystick 0 is on lpt3 */ } if (use_lpt2) { for (i=3;i>0;i--) joytypes[i]=joytypes[i-1]; /*see above*/ joytypes[0]=joy_lpt2; } if (use_lpt1) { for (i=3;i>0;i--) joytypes[i]=joytypes[i-1]; joytypes[0]=joy_lpt1; } if (joy_in && !joycfg) { for (i=3;i>0;i--) joytypes[i]=joytypes[i-1]; joytypes[0]=joy_analog; } if (joyswap) { int help=joytypes[0]; joytypes[0]=joytypes[1]; joytypes[1]=help; } /*end of compatibility part*/ /*check, if joystick configuration is valid*/ for (i=0;i<4;i++) switch (joytypes[i]) { case joy_lpt1: if (!test_LPTjoy(1,lptport+i)) joytypes[i]=joy_off; break; case joy_lpt2: if (!test_LPTjoy(2,lptport+i)) joytypes[i]=joy_off; break; case joy_lpt3: if (!test_LPTjoy(3,lptport+i)) joytypes[i]=joy_off; break; case joy_analog: if (!joy_in) joytypes[i]=joy_off; break; } /* do not forget any scancode */ for (i=0;i<256;i++) keyforget[i]=0; /* mark all used scancodes to forget*/ for (i=0;i<4;i++) { j=0; while (j<4 && joytypes[j]!=(i+joy_keyset0)) j++; if (j<4) /*keyset i is used */ for (j=0;j<9;j++) keyforget[keysets[i][j]]=1; else keyset_used[i]=0; } SetupVgaEnvironment(); }
void SetupVgaEnvironment() { int a, i; union REGS rg; __dpmi_regs d_rg; UBYTE ctab[768]; if (use_vesa) { /*try to open VESA mode*/ use_vesa=VESA_open(vesa_mode,vesa_memptr,vesa_memsize,&vesa_linear,&vesa_selector); } if (!use_vesa) /*if '-novesa' specified or VESA_open failed */ switch(video_mode) { case 0: rg.x.ax = 0x0013; int86(0x10, &rg, &rg); /*vga 320x200*/ break; case 1: x_open(2); /*xmode 320x240*/ break; case 2: case 3: x_open(5); /*xmode 320x480*/ break; } screen_visible_x1 = first_col; screen_visible_x2 = first_col + 320; if (video_mode == 0) { screen_visible_y1 = first_lno; screen_visible_y2 = first_lno + 200; } else { screen_visible_y1 = 0; screen_visible_y2 = 240; } vga_started = 1; /* setting all palette at once is faster....*/ for (a = 0, i = 0; a < 256; a++) { ctab[i++]=(colortable[a] >> 18) & 0x3f; ctab[i++]=(colortable[a] >> 10) & 0x3f; ctab[i++]=(colortable[a] >> 2) & 0x3f; } /*copy ctab to djgpp transfer buffer in DOS memory*/ dosmemput(ctab,768,__tb&0xfffff); d_rg.x.ax=0x1012; d_rg.x.bx=0; d_rg.x.cx=256; d_rg.x.dx=__tb&0xf; /*offset of transfer buffer*/ d_rg.x.es=(__tb >> 4) & 0xffff; /*segment of transfer buffer*/ __dpmi_int(0x10,&d_rg); /*VGA set palette block*/ /* initialize mouse */ if (mouse_mode != MOUSE_OFF) { union REGS rg; rg.x.ax = 0; int86(0x33, &rg, &rg); if (rg.x.ax != 0xffff) { Aprint("Can't find mouse!"); mouse_mode = MOUSE_OFF; } } key_init(); /*initialize keyboard handler*/ }
static int decode_FA(void) { unsigned char c; if (working) { Aprint("Trying to start section but last section never had an end section block."); return 0; } c=fgetc(fin); if( feof(fin) ) { show_file_error( fin ); return 0; } density=((c & 0x70) >> 4); last=((c & 0x80) >> 7); switch(density) { case 0: maxsec=720; secsize=128; break; case 2: maxsec=720; secsize=256; break; case 4: maxsec=1040; secsize=128; break; default: Aprint( "Density type is unknown, density type=%u",density); return 0; } if (createdisk == 0) { createdisk = 1; /* write out atr header */ /* special code, 0x0296 */ if( write_atari16(fout,0x296) == 0 ) return 0; /* image size (low) */ if( write_atari16(fout,(short)(((long)maxsec * secsize) >> 4)) == 0 ) return 0; /* sector size */ if( write_atari16(fout,secsize) == 0 ) return 0; /* image size (high) */ if( write_atari16(fout,(short)(((long)maxsec * secsize) >> 20)) == 0 ) return 0; /* 8 bytes unused */ if( write_atari16(fout,0) == 0 ) return 0; if( write_atari16(fout,0) == 0 ) return 0; if( write_atari16(fout,0) == 0 ) return 0; if( write_atari16(fout,0) == 0 ) return 0; memset(buf,0,256); for (cursec=0; cursec<maxsec; cursec++) { if( fwrite(buf,secsize,1,fout) != 1 ) { Aprint( "Error writing to output file" ); return 0; } } }
int dcmtoatr(FILE *fin, FILE *fout, const char *input, char *output ) { int archivetype; /* Block type for first block */ int blocktype; /* Current block type */ int tmp; /* Temporary for read without clobber on eof */ init_globals( fin, fout ); Aprint( "Converting %s to %s", input, output ); if( !fin || !fout ) { Aprint( "Programming error - NULL file specified for conversion" ); return 0; } archivetype = blocktype = fgetc(fin); if( archivetype == EOF ) { show_file_error( fin ); return 0; } switch(blocktype) { case 0xF9: case 0xFA: break; default: Aprint("0x%02X is not a known header block at start of input file",blocktype); return 0; } rewind(fin); while( 1 ) { if (feof(fin)) { fflush(stdout); /* Possible buffered I/O confusion fix */ if ((!last) && (blocktype == 0x45) && (archivetype == 0xF9)) { Aprint("Multi-part archive error."); Aprint("To process these files, you must first combine the files into a single file."); Aprint("COPY /B file1.dcm+file2.dcm+file3.dcm newfile.dcm from the DOS prompt"); } else { Aprint("EOF before end block, input file likely corrupt"); } return 0; } if (working) { if (soffset() != ftell(fout)) { Aprint("Output desyncronized, possibly corrupt dcm file. fin=%lu fout=%lu != %lu cursec=%u secsize=%u", ftell(fin),ftell(fout),soffset(),cursec,secsize); return 0; } } tmp = fgetc(fin); /* blocktype is needed on EOF error--don't corrupt it */ if( tmp == EOF ) { show_file_error( fin ); return 0; } blocktype = tmp; switch(blocktype) { case 0xF9: case 0xFA: /* New block */ if( decode_FA() == 0 ) return 0; break; case 0x45: /* End block */ working=0; if (last) return 1; /* Normal exit */ break; case 0x41: case 0xC1: if( decode_C1() == 0 ) return 0; break; case 0x43: case 0xC3: if( decode_C3() == 0 ) return 0; break; case 0x44: case 0xC4: if( decode_C4() == 0 ) return 0; break; case 0x46: case 0xC6: if( decode_C6() == 0 ) return 0; break; case 0x47: case 0xC7: if( decode_C7() == 0 ) return 0; break; default: Aprint("0x%02X is not a known block type. File may be corrupt.",blocktype); return 0; } /* end case */ if ((blocktype != 0x45) && (blocktype != 0xFA) && (blocktype != 0xF9)) { if (!(blocktype & 0x80)) { cursec=read_atari16(fin); if( fseek(fout, soffset(), SEEK_SET) != 0 ) { Aprint( "Failed a seek in output file, cannot continue" ); return 0; } } else { cursec++; if(cursec==4 && secsize!=128) fseek(fout,(secsize-128)*3,SEEK_CUR); } } } return 0; /* Should never be executed */ }
/* Opens a ZLIB compressed (gzip) file, creates a temporary filename, and decompresses the contents of the .gz file to the temporary file name. Note that *outfilename is actually blank coming in and is filled by mkstemp */ FILE * openzlib(int diskno, const char *infilename, char *outfilename ) { #ifndef HAVE_LIBZ Aprint( "This executable cannot decompress ZLIB files" ); return NULL; #else gzFile gzSource; FILE *file = NULL, *outfile = NULL; char *curptr = outfilename; char *zlib_buffer = NULL; if( zlib_capable() == -1 ) { Aprint( "This executable cannot decompress ZLIB files" ); return NULL; } zlib_buffer = malloc( ZLIB_BUFFER_SIZE + 1 ); if( !zlib_buffer ) { Aprint( "Could not obtain memory for zlib decompression" ); return NULL; } curptr += prepend_tmpfile_path( outfilename ); strcpy(curptr,"TMP_XXXXXX\0"); outfile = fdopen(mkstemp(curptr), "wb"); if (!outfile) { Aprint( "Could not open temporary file" ); free( zlib_buffer ); return NULL; } gzSource = GZOPEN( infilename, "rb" ); if( !gzSource ) { Aprint( "ZLIB could not open file %s", infilename ); fclose( outfile ); } else /* Convert the gzip file to the temporary file */ { int result, temp; Aprint( "Converting %s to %s", infilename, outfilename ); do { result = GZREAD( gzSource, &zlib_buffer[0], ZLIB_BUFFER_SIZE ); if( result > 0 ) { if( fwrite(zlib_buffer, 1, result, outfile) != result ) { Aprint( "Error writing to temporary file %s, disk may be full", outfilename ); result = -1; } } } while( result == ZLIB_BUFFER_SIZE ); temp = GZCLOSE( gzSource ); fclose( outfile ); if( result > -1 ) file = fopen(outfilename, "rb"); else { Aprint( "Error while parsing gzip file" ); file = NULL; } } if(!file) { if( zlib_buffer ) free( zlib_buffer ); Aprint( "Removing temporary file %s", outfilename ); remove( outfilename ); } return file; #endif /* HAVE_LIBZ */ }