diff --git a/zsnes/src/Makefile.in b/zsnes/src/Makefile.in index 5ad5ed2b..29e9b35a 100644 --- a/zsnes/src/Makefile.in +++ b/zsnes/src/Makefile.in @@ -53,7 +53,7 @@ JMAOBJ=${JMADIR}/7zlzma.o ${JMADIR}/crc32.o ${JMADIR}/iiostrm.o\ ${JMADIR}/winout.o ${JMADIR}/zsnesjma.o MAINOBJ=cfgload.o cfgparse.o endmem.o init.o initc.o uic.o patch.o ui.o vcache.o\ - version.o zmovie.o zstate.o debug.o zloader.o + version.o zmovie.o zstate.o debug.o zloader.o md.o NETOBJ= #${NETDIR}/ztcp.o @@ -150,7 +150,11 @@ uic.o: uic.c asm_call.h gblhdr.h vcache.o: vcache.asm macros.mac version.o: version.c zloader.o: zloader.c gblhdr.h -zmovie.o: zmovie.c asm_call.h gblhdr.h gblvars.h numconv.h +md.o: md.psr ${PSR} + ./${PSR} -D__UNIXSDL__ -cheader md.h -fname movie temppsr.c $< + @CC@ -I. -O1 -o $@ -c temppsr.c + rm -f temppsr.c +zmovie.o: zmovie.c asm_call.h gblhdr.h gblvars.h numconv.h md.o zstate.o: zstate.c asm_call.h gblhdr.h gblvars.h numconv.h ${CHIPDIR}/c4emu.o: ${CHIPDIR}/c4emu.c gblhdr.h diff --git a/zsnes/src/md.psr b/zsnes/src/md.psr new file mode 100644 index 00000000..abfae56c --- /dev/null +++ b/zsnes/src/md.psr @@ -0,0 +1,9 @@ +md_ntsc times 20 db "59649/995" +md_pal times 5 db "50/1" +md_prog times 50 db "mencoder" +md_raw times 100 db "-demuxer rawvideo -rawvideo format=0x42475218:w=256:h=224:size=172032" +md_other times 50 db "-aspect 4/3 -mc 0 -nosound" +md_file times 50 db "video.avi" +md_uncompressed times 125 db "$md_prog $md_other $md_raw:fps=$md_video_rate -ovc copy -o $md_file -" +md_x264 times 125 db "$md_prog $md_other $md_raw:fps=$md_video_rate -ovc x264 -x264encopts qp_constant=0:frameref=15 -o $md_file -" +md_ffv1 times 125 db "$md_prog $md_other $md_raw:fps=$md_video_rate -ovc lavc -lavcopts vcodec=ffv1:vstrict=-2 -o $md_file -" diff --git a/zsnes/src/zmovie.c b/zsnes/src/zmovie.c index fc969b7b..c93c97a0 100644 --- a/zsnes/src/zmovie.c +++ b/zsnes/src/zmovie.c @@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifdef __UNIXSDL__ #include "gblhdr.h" #define DIR_SLASH "/" +#define WRITE_BINARY "w" #else #include #include @@ -38,10 +39,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #endif #define DIR_SLASH "\\" +#define WRITE_BINARY "wb" #endif #include "gblvars.h" #include "asm_call.h" #include "numconv.h" +#include "md.h" #ifndef __WIN32__ #define mkdir(path) mkdir(path, (S_IRWXU|S_IRWXG|S_IRWXO)) //0777 @@ -1845,13 +1848,9 @@ Code for dumping raw video */ -#define RAW_BUFFER_FRAMES 10 #define RAW_BUFFER_SAMPLES 12800 #define RAW_WIDTH 256 #define RAW_HEIGHT 224 -#define RAW_PIXEL_SIZE 4 -#define RAW_FRAME_SIZE (RAW_WIDTH*RAW_HEIGHT) -#define RAW_PIXEL_FRAME_SIZE (RAW_FRAME_SIZE*RAW_PIXEL_SIZE) //NTSC FPS is 59.948743718592964824120603015060 in AVI that's a fraction of 59649/995 //which equals 59.948743718592964824120603015075, so videos should not desync for several millinium @@ -1862,16 +1861,70 @@ Code for dumping raw video //59.948743718592964824120603015060 = SAMPLE_NTSC_HI*32000/SAMPLE_NTSC_LO *2 #define SAMPLE_NTSC_HI 31840000ULL #define SAMPLE_NTSC_LO 59649ULL +//Used by raw videos for calculating sample rate in NTSC mode +//Code by Bisqwit //0 = None; 1 Logging, but not now, 2 Log now unsigned char AudioLogging; +extern unsigned char MovieVideoMode; +extern unsigned char MovieAudioMode; + +#define PICK_HELP(var) if (!strncmp(*str, "$"#var, strlen(#var)+1)) { *str += strlen(#var)+1; return(var); } + +static char *pick_var(char **str) +{ + PICK_HELP(md_prog); + PICK_HELP(md_raw); + PICK_HELP(md_other); + PICK_HELP(md_file); + if (!strncmp(*str, "$md_video_rate", strlen("$md_video_rate"))) + { + *str += strlen("$md_video_rate"); + return(romispal ? md_pal : md_ntsc); + } + fprintf(stderr, "Unknown Variable: %s", *str); + return(""); +} + +FILE *open_movie_file() +{ + char command[400], *p, *var; + read_movie_vars("zmovie.cfg"); + + *command = 0; + + switch (MovieVideoMode) + { + case 2: p = md_uncompressed; break; + case 3: p = md_ffv1; break; + case 4: p = md_x264; break; + default: p = "$"; break; + } + + while (*p) + { + if ((var = strchr(p, '$'))) + { + strncat(command, p, var - p); + strcat(command, pick_var(&var)); + p = var; + } + else + { + strcat(command, p); + break; + } + } + + puts(command); + return(popen(command, WRITE_BINARY)); +} + struct { FILE *vp; - unsigned int *frame_buffer; - size_t frame_index; FILE *ap; unsigned short *sample_buffer; @@ -1888,96 +1941,108 @@ static void raw_video_close() { if (raw_vid.vp) { - if (raw_vid.frame_buffer) + switch (MovieVideoMode) { - if (raw_vid.frame_index) - { - fwrite(raw_vid.frame_buffer, RAW_PIXEL_FRAME_SIZE, raw_vid.frame_index, raw_vid.vp); - } - - free(raw_vid.frame_buffer); + case 1: + fclose(raw_vid.vp); + break; + case 2: case 3: case 4: + pclose(raw_vid.vp); + break; } - fclose(raw_vid.vp); raw_vid.vp = 0; + } - if (raw_vid.ap) + if (raw_vid.ap) + { + if (raw_vid.sample_buffer) { - if (raw_vid.sample_buffer) + size_t file_size; + if (raw_vid.sample_index) { - size_t file_size; - if (raw_vid.sample_index) - { - fwrite(raw_vid.sample_buffer, 2, raw_vid.frame_index, raw_vid.ap); //Sample is 2 bytes - } - - free(raw_vid.sample_buffer); - - file_size = ftell(raw_vid.ap); //Get file size - if (!fseek(raw_vid.ap, 4, SEEK_SET)) //Seek to after RIFF header - { - fwrite4(file_size - 8, raw_vid.ap); //Don't include header or this write, -8 - } - if (!fseek(raw_vid.ap, raw_vid.aud_dsize_pos, SEEK_SET)) //Seek to where the audio data size goes - { - //Data size is remainder of file, which is file size, less current position, plus - //The 4 bytes needed to hold the data size - fwrite4(file_size - (raw_vid.aud_dsize_pos+4), raw_vid.ap); - } - fclose(raw_vid.ap); - raw_vid.ap = 0; + fwrite(raw_vid.sample_buffer, 2, raw_vid.sample_index, raw_vid.ap); //Sample is 2 bytes } - AudioLogging = 0; + + free(raw_vid.sample_buffer); + + file_size = ftell(raw_vid.ap); //Get file size + if (!fseek(raw_vid.ap, 4, SEEK_SET)) //Seek to after RIFF header + { + fwrite4(file_size - 8, raw_vid.ap); //Don't include header or this write, -8 + } + if (!fseek(raw_vid.ap, raw_vid.aud_dsize_pos, SEEK_SET)) //Seek to where the audio data size goes + { + //Data size is remainder of file, which is file size, less current position, plus + //The 4 bytes needed to hold the data size + fwrite4(file_size - (raw_vid.aud_dsize_pos+4), raw_vid.ap); + } + fclose(raw_vid.ap); + raw_vid.ap = 0; } + AudioLogging = 0; } } static bool raw_video_open(const char *video_filename, const char *audio_filename) { - memset(&raw_vid, 0, sizeof(raw_vid)); - if ((raw_vid.vp = fopen(video_filename, "wb"))) + switch (MovieVideoMode) { - if ((raw_vid.frame_buffer = (unsigned int *)malloc(RAW_PIXEL_FRAME_SIZE*RAW_BUFFER_FRAMES))) + case 1: + raw_vid.vp = fopen(video_filename, "wb"); + break; + + case 2: case 3: case 4: + raw_vid.vp = open_movie_file(); + break; + + default: + return(false); + break; + } + + if (!MovieAudioMode && raw_vid.vp) + { + return(true); + } + + if (!MovieVideoMode || raw_vid.vp) + { + if ((raw_vid.ap = fopen(audio_filename, "wb"))) { - if ((raw_vid.ap = fopen(audio_filename, "wb"))) + if ((raw_vid.sample_buffer = (unsigned short *)malloc(RAW_BUFFER_SAMPLES*sizeof(short)))) { - if ((raw_vid.sample_buffer = (unsigned short *)malloc(RAW_BUFFER_SAMPLES*sizeof(short)))) + fputs("RIFF", raw_vid.ap); //header + fwrite4(~0, raw_vid.ap); //file size - unknown till file close + fputs("WAVEfmt ", raw_vid.ap); //format + fwrite4(0x12, raw_vid.ap); //fmt size + fwrite2(1, raw_vid.ap); //fmt type (PCM) + fwrite2(2, raw_vid.ap); //channels + fwrite4(32000, raw_vid.ap); //sample rate + fwrite4(32000*4, raw_vid.ap); //byte rate (sample rate*block align) + fwrite2(16/8*2, raw_vid.ap); //block align (SignificantBitsPerSample / 8 * NumChannels) + fwrite2(16, raw_vid.ap); //Significant bits per sample + fwrite2(0, raw_vid.ap); //Extra format bytes + fputs("data", raw_vid.ap); //data header + raw_vid.aud_dsize_pos = ftell(raw_vid.ap); //Save current position for use later + fwrite4(~0, raw_vid.ap); //data size - unknown till file close + + if (!romispal) { - fputs("RIFF", raw_vid.ap); //header - fwrite4(~0, raw_vid.ap); //file size - unknown till file close - fputs("WAVEfmt ", raw_vid.ap); //format - fwrite4(0x12, raw_vid.ap); //fmt size - fwrite2(1, raw_vid.ap); //fmt type (PCM) - fwrite2(2, raw_vid.ap); //channels - fwrite4(32000, raw_vid.ap); //sample rate - fwrite4(32000*4, raw_vid.ap); //byte rate (sample rate*block align) - fwrite2(16/8*2, raw_vid.ap); //block align (SignificantBitsPerSample / 8 * NumChannels) - fwrite2(16, raw_vid.ap); //Significant bits per sample - fwrite2(0, raw_vid.ap); //Extra format bytes - fputs("data", raw_vid.ap); //data header - raw_vid.aud_dsize_pos = ftell(raw_vid.ap); //Save current position for use later - fwrite4(~0, raw_vid.ap); //data size - unknown till file close - - if (!romispal) - { - raw_vid.sample_ntsc_hi = SAMPLE_NTSC_HI; - raw_vid.sample_ntsc_lo = SAMPLE_NTSC_LO; - raw_vid.sample_ntsc_balance = SAMPLE_NTSC_HI; - } - - AudioLogging = 1; - return(true); + raw_vid.sample_ntsc_hi = SAMPLE_NTSC_HI; + raw_vid.sample_ntsc_lo = SAMPLE_NTSC_LO; + raw_vid.sample_ntsc_balance = SAMPLE_NTSC_HI; } + + AudioLogging = 1; + return(true); } } - raw_video_close(); } + raw_video_close(); return(false); } -//Used by raw videos for calculating sample rate in NTSC mode -//Code by Bisqwit - #define PIXEL (vidbuffer[(i*288) + j + 16]) static void raw_video_write_frame() { @@ -1985,26 +2050,15 @@ static void raw_video_write_frame() { extern unsigned short *vidbuffer; size_t i, j; - unsigned int *pixel_dest = raw_vid.frame_buffer + raw_vid.frame_index*RAW_FRAME_SIZE; //Use zsKnight's 16 to 32 bit color conversion (optimized by Nach) for (i = 0; i < RAW_HEIGHT; i++) { - unsigned int *scanline = pixel_dest + i*RAW_WIDTH; for (j = 0; j < RAW_WIDTH; j++) { - scanline[j] = ((PIXEL&0xF800) << 8) | ((PIXEL&0x07E0) << 5) | - ((PIXEL&0x001F) << 3) | 0xFF000000; + fwrite3(((PIXEL&0xF800) << 8) | ((PIXEL&0x07E0) << 5) | ((PIXEL&0x001F) << 3), raw_vid.vp); } } - - raw_vid.frame_index++; - - if (raw_vid.frame_index == RAW_BUFFER_FRAMES) - { - fwrite(raw_vid.frame_buffer, RAW_PIXEL_FRAME_SIZE, RAW_BUFFER_FRAMES, raw_vid.vp); - raw_vid.frame_index = 0; - } } if (raw_vid.ap) @@ -2052,6 +2106,7 @@ static void raw_video_write_frame() } + ///////////////////////////////////////////////////////// /*