revision 295:6637664291a8
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 295:6637664291a8 |
parent | 294:a5beff9b2b85 |
child | 296:1aa1c5ba59fd |
author | nkeynes |
date | Tue Jan 16 10:34:46 2007 +0000 (17 years ago) |
Bug 24: Initial implementation of "save scene" function
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/dreamcast.c | view | annotate | diff | log | ||
src/dreamcast.h | view | annotate | diff | log | ||
src/pvr2/pvr2.c | view | annotate | diff | log | ||
src/pvr2/pvr2.h | view | annotate | diff | log | ||
src/pvr2/rendsave.c | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Tue Jan 16 09:18:32 2007 +00001.2 +++ b/src/Makefile.am Tue Jan 16 10:34:46 2007 +00001.3 @@ -23,7 +23,7 @@1.4 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \1.5 pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \1.6 pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \1.7 - pvr2/texcache.c pvr2/yuv.c \1.8 + pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c \1.9 maple/maple.c maple/maple.h \1.10 maple/controller.c maple/controller.h \1.11 gui/support.c gui/support.h \
2.1 --- a/src/Makefile.in Tue Jan 16 09:18:32 2007 +00002.2 +++ b/src/Makefile.in Tue Jan 16 10:34:46 2007 +00002.3 @@ -157,7 +157,7 @@2.4 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \2.5 pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \2.6 pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \2.7 - pvr2/texcache.c pvr2/yuv.c \2.8 + pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c \2.9 maple/maple.c maple/maple.h \2.10 maple/controller.c maple/controller.h \2.11 gui/support.c gui/support.h \2.12 @@ -195,13 +195,13 @@2.13 aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) pvr2mem.$(OBJEXT) \2.14 tacore.$(OBJEXT) render.$(OBJEXT) rendcore.$(OBJEXT) \2.15 rendbkg.$(OBJEXT) rendsort.$(OBJEXT) texcache.$(OBJEXT) \2.16 - yuv.$(OBJEXT) maple.$(OBJEXT) controller.$(OBJEXT) \2.17 - support.$(OBJEXT) interface.$(OBJEXT) callbacks.$(OBJEXT) \2.18 - gui.$(OBJEXT) mmr_win.$(OBJEXT) debug_win.$(OBJEXT) \2.19 - dump_win.$(OBJEXT) loader.$(OBJEXT) bootstrap.$(OBJEXT) \2.20 - util.$(OBJEXT) display.$(OBJEXT) audio_null.$(OBJEXT) \2.21 - audio_esd.$(OBJEXT) video_null.$(OBJEXT) video_gtk.$(OBJEXT) \2.22 - video_x11.$(OBJEXT) video_gl.$(OBJEXT)2.23 + yuv.$(OBJEXT) rendsave.$(OBJEXT) maple.$(OBJEXT) \2.24 + controller.$(OBJEXT) support.$(OBJEXT) interface.$(OBJEXT) \2.25 + callbacks.$(OBJEXT) gui.$(OBJEXT) mmr_win.$(OBJEXT) \2.26 + debug_win.$(OBJEXT) dump_win.$(OBJEXT) loader.$(OBJEXT) \2.27 + bootstrap.$(OBJEXT) util.$(OBJEXT) display.$(OBJEXT) \2.28 + audio_null.$(OBJEXT) audio_esd.$(OBJEXT) video_null.$(OBJEXT) \2.29 + video_gtk.$(OBJEXT) video_x11.$(OBJEXT) video_gl.$(OBJEXT)2.30 lxdream_OBJECTS = $(am_lxdream_OBJECTS)2.31 lxdream_DEPENDENCIES =2.32 lxdream_LDFLAGS =2.33 @@ -227,16 +227,16 @@2.34 @AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/nrg.Po \2.35 @AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/pvr2mem.Po \2.36 @AMDEP_TRUE@ ./$(DEPDIR)/rendbkg.Po ./$(DEPDIR)/rendcore.Po \2.37 -@AMDEP_TRUE@ ./$(DEPDIR)/render.Po ./$(DEPDIR)/rendsort.Po \2.38 -@AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4core.Po \2.39 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \2.40 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \2.41 -@AMDEP_TRUE@ ./$(DEPDIR)/syscall.Po ./$(DEPDIR)/tacore.Po \2.42 -@AMDEP_TRUE@ ./$(DEPDIR)/texcache.Po ./$(DEPDIR)/timer.Po \2.43 -@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gl.Po \2.44 -@AMDEP_TRUE@ ./$(DEPDIR)/video_gtk.Po ./$(DEPDIR)/video_null.Po \2.45 -@AMDEP_TRUE@ ./$(DEPDIR)/video_x11.Po ./$(DEPDIR)/watch.Po \2.46 -@AMDEP_TRUE@ ./$(DEPDIR)/yuv.Po2.47 +@AMDEP_TRUE@ ./$(DEPDIR)/render.Po ./$(DEPDIR)/rendsave.Po \2.48 +@AMDEP_TRUE@ ./$(DEPDIR)/rendsort.Po ./$(DEPDIR)/scif.Po \2.49 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \2.50 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4mem.Po ./$(DEPDIR)/sh4mmio.Po \2.51 +@AMDEP_TRUE@ ./$(DEPDIR)/support.Po ./$(DEPDIR)/syscall.Po \2.52 +@AMDEP_TRUE@ ./$(DEPDIR)/tacore.Po ./$(DEPDIR)/texcache.Po \2.53 +@AMDEP_TRUE@ ./$(DEPDIR)/timer.Po ./$(DEPDIR)/util.Po \2.54 +@AMDEP_TRUE@ ./$(DEPDIR)/video_gl.Po ./$(DEPDIR)/video_gtk.Po \2.55 +@AMDEP_TRUE@ ./$(DEPDIR)/video_null.Po ./$(DEPDIR)/video_x11.Po \2.56 +@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po ./$(DEPDIR)/yuv.Po2.57 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \2.58 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)2.59 CCLD = $(CC)2.60 @@ -325,6 +325,7 @@2.61 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendbkg.Po@am__quote@2.62 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendcore.Po@am__quote@2.63 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render.Po@am__quote@2.64 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendsave.Po@am__quote@2.65 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendsort.Po@am__quote@2.66 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scif.Po@am__quote@2.67 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4core.Po@am__quote@2.68 @@ -960,6 +961,28 @@2.69 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.70 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o yuv.obj `if test -f 'pvr2/yuv.c'; then $(CYGPATH_W) 'pvr2/yuv.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/yuv.c'; fi`2.72 +rendsave.o: pvr2/rendsave.c2.73 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rendsave.o -MD -MP -MF "$(DEPDIR)/rendsave.Tpo" \2.74 +@am__fastdepCC_TRUE@ -c -o rendsave.o `test -f 'pvr2/rendsave.c' || echo '$(srcdir)/'`pvr2/rendsave.c; \2.75 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rendsave.Tpo" "$(DEPDIR)/rendsave.Po"; \2.76 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/rendsave.Tpo"; exit 1; \2.77 +@am__fastdepCC_TRUE@ fi2.78 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/rendsave.c' object='rendsave.o' libtool=no @AMDEPBACKSLASH@2.79 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rendsave.Po' tmpdepfile='$(DEPDIR)/rendsave.TPo' @AMDEPBACKSLASH@2.80 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.81 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rendsave.o `test -f 'pvr2/rendsave.c' || echo '$(srcdir)/'`pvr2/rendsave.c2.82 +2.83 +rendsave.obj: pvr2/rendsave.c2.84 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rendsave.obj -MD -MP -MF "$(DEPDIR)/rendsave.Tpo" \2.85 +@am__fastdepCC_TRUE@ -c -o rendsave.obj `if test -f 'pvr2/rendsave.c'; then $(CYGPATH_W) 'pvr2/rendsave.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/rendsave.c'; fi`; \2.86 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rendsave.Tpo" "$(DEPDIR)/rendsave.Po"; \2.87 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/rendsave.Tpo"; exit 1; \2.88 +@am__fastdepCC_TRUE@ fi2.89 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/rendsave.c' object='rendsave.obj' libtool=no @AMDEPBACKSLASH@2.90 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rendsave.Po' tmpdepfile='$(DEPDIR)/rendsave.TPo' @AMDEPBACKSLASH@2.91 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.92 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rendsave.obj `if test -f 'pvr2/rendsave.c'; then $(CYGPATH_W) 'pvr2/rendsave.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/rendsave.c'; fi`2.93 +2.94 maple.o: maple/maple.c2.95 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maple.o -MD -MP -MF "$(DEPDIR)/maple.Tpo" \2.96 @am__fastdepCC_TRUE@ -c -o maple.o `test -f 'maple/maple.c' || echo '$(srcdir)/'`maple/maple.c; \
3.1 --- a/src/dreamcast.c Tue Jan 16 09:18:32 2007 +00003.2 +++ b/src/dreamcast.c Tue Jan 16 10:34:46 2007 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: dreamcast.c,v 1.20 2007-01-12 10:16:02 nkeynes Exp $3.6 + * $Id: dreamcast.c,v 1.21 2007-01-16 10:34:46 nkeynes Exp $3.7 * Central switchboard for the system. This pulls all the individual modules3.8 * together into some kind of coherent structure. This is also where you'd3.9 * add Naomi support, if I ever get a board to play with...3.10 @@ -371,9 +371,6 @@3.12 /********************************* Save States *****************************/3.14 -#define DREAMCAST_SAVE_MAGIC "%!-lxDream!Save\0"3.15 -#define DREAMCAST_SAVE_VERSION 0x000100003.16 -3.17 struct save_state_header {3.18 char magic[16];3.19 uint32_t version;
4.1 --- a/src/dreamcast.h Tue Jan 16 09:18:32 2007 +00004.2 +++ b/src/dreamcast.h Tue Jan 16 10:34:46 2007 +00004.3 @@ -1,5 +1,5 @@4.4 /**4.5 - * $Id: dreamcast.h,v 1.11 2006-07-02 04:59:00 nkeynes Exp $4.6 + * $Id: dreamcast.h,v 1.12 2007-01-16 10:34:46 nkeynes Exp $4.7 *4.8 * Public interface for dreamcast.c -4.9 * Central switchboard for the system. This pulls all the individual modules4.10 @@ -58,9 +58,15 @@4.11 gboolean dreamcast_load_config( const gchar *filename );4.12 gboolean dreamcast_save_config( const gchar *filename );4.14 +#define DREAMCAST_SAVE_MAGIC "%!-lxDream!Save\0"4.15 +#define DREAMCAST_SAVE_VERSION 0x000100004.16 +4.17 int dreamcast_save_state( const gchar *filename );4.18 int dreamcast_load_state( const gchar *filename );4.20 +#define SCENE_SAVE_MAGIC "%!-lxDream!Scene"4.21 +#define SCENE_SAVE_VERSION 0x000100004.22 +4.23 extern struct dreamcast_config_group dreamcast_config_root[];4.25 /* Global config values */
5.1 --- a/src/pvr2/pvr2.c Tue Jan 16 09:18:32 2007 +00005.2 +++ b/src/pvr2/pvr2.c Tue Jan 16 10:34:46 2007 +00005.3 @@ -1,5 +1,5 @@5.4 /**5.5 - * $Id: pvr2.c,v 1.39 2007-01-15 08:32:09 nkeynes Exp $5.6 + * $Id: pvr2.c,v 1.40 2007-01-16 10:34:46 nkeynes Exp $5.7 *5.8 * PVR2 (Video) Core module implementation and MMIO registers.5.9 *5.10 @@ -69,7 +69,7 @@5.11 uint32_t irq_vpos1;5.12 uint32_t irq_vpos2;5.13 uint32_t odd_even_field; /* 1 = odd, 0 = even */5.14 -5.15 + gchar *save_next_render_filename;5.16 /* timing */5.17 uint32_t dot_clock;5.18 uint32_t total_lines;5.19 @@ -123,6 +123,7 @@5.20 texcache_init();5.21 pvr2_reset();5.22 pvr2_ta_reset();5.23 + pvr2_state.save_next_render_filename = NULL;5.24 }5.26 static void pvr2_reset( void )5.27 @@ -150,13 +151,17 @@5.28 {5.29 fwrite( &pvr2_state, sizeof(pvr2_state), 1, f );5.30 pvr2_ta_save_state( f );5.31 + pvr2_yuv_save_state( f );5.32 }5.34 static int pvr2_load_state( FILE *f )5.35 {5.36 if( fread( &pvr2_state, sizeof(pvr2_state), 1, f ) != 1 )5.37 return 1;5.38 - return pvr2_ta_load_state(f);5.39 + if( pvr2_ta_load_state(f) ) {5.40 + return 1;5.41 + }5.42 + return pvr2_yuv_load_state(f);5.43 }5.45 /**5.46 @@ -202,6 +207,17 @@5.47 return pvr2_state.frame_count;5.48 }5.50 +gboolean pvr2_save_next_scene( const gchar *filename )5.51 +{5.52 + if( pvr2_state.save_next_render_filename != NULL ) {5.53 + g_free( pvr2_state.save_next_render_filename );5.54 + }5.55 + pvr2_state.save_next_render_filename = g_strdup(filename);5.56 + return TRUE;5.57 +}5.58 +5.59 +5.60 +5.61 /**5.62 * Display the next frame, copying the current contents of video ram to5.63 * the window. If the video configuration has changed, first recompute the5.64 @@ -288,9 +304,15 @@5.65 val &= 0x00000007; /* Do stuff? */5.66 MMIO_WRITE( PVR2, reg, val );5.67 break;5.68 - case RENDER_START:5.69 - if( val == 0xFFFFFFFF || val == 0x00000001 )5.70 - pvr2_render_scene();5.71 + case RENDER_START: /* Don't really care what value */5.72 + if( pvr2_state.save_next_render_filename != NULL ) {5.73 + if( pvr2_render_save_scene(pvr2_state.save_next_render_filename) == 0 ) {5.74 + INFO( "Saved scene to %s", pvr2_state.save_next_render_filename);5.75 + }5.76 + g_free( pvr2_state.save_next_render_filename );5.77 + pvr2_state.save_next_render_filename = NULL;5.78 + }5.79 + pvr2_render_scene();5.80 break;5.81 case RENDER_POLYBASE:5.82 MMIO_WRITE( PVR2, reg, val&0x00F00000 );
6.1 --- a/src/pvr2/pvr2.h Tue Jan 16 09:18:32 2007 +00006.2 +++ b/src/pvr2/pvr2.h Tue Jan 16 10:34:46 2007 +00006.3 @@ -1,5 +1,5 @@6.4 /**6.5 - * $Id: pvr2.h,v 1.21 2007-01-15 12:58:05 nkeynes Exp $6.6 + * $Id: pvr2.h,v 1.22 2007-01-16 10:34:46 nkeynes Exp $6.7 *6.8 * PVR2 (video chip) functions and macros.6.9 *6.10 @@ -64,6 +64,7 @@6.11 void pvr2_next_frame( void );6.12 void pvr2_set_base_address( uint32_t );6.13 int pvr2_get_frame_count( void );6.14 +gboolean pvr2_save_next_scene( const gchar *filename );6.16 #define PVR2_CMD_END_OF_LIST 0x006.17 #define PVR2_CMD_USER_CLIP 0x20
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00007.2 +++ b/src/pvr2/rendsave.c Tue Jan 16 10:34:46 2007 +00007.3 @@ -0,0 +1,97 @@7.4 +/**7.5 + * $Id: rendsave.c,v 1.1 2007-01-16 10:34:46 nkeynes Exp $7.6 + *7.7 + * Scene-save support. This is mainly for test/debug purposes.7.8 + *7.9 + * Copyright (c) 2005 Nathan Keynes.7.10 + *7.11 + * This program is free software; you can redistribute it and/or modify7.12 + * it under the terms of the GNU General Public License as published by7.13 + * the Free Software Foundation; either version 2 of the License, or7.14 + * (at your option) any later version.7.15 + *7.16 + * This program is distributed in the hope that it will be useful,7.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of7.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the7.19 + * GNU General Public License for more details.7.20 + */7.21 +7.22 +#include <stdio.h>7.23 +#include <errno.h>7.24 +#include <time.h>7.25 +#include "pvr2/pvr2.h"7.26 +#include "dreamcast.h"7.27 +7.28 +/**7.29 + * Size of pages for the purposes of saving - this has nothing to do with the7.30 + * actual page size, of course.7.31 + */7.32 +#define SAVE_PAGE_SIZE 10247.33 +#define SAVE_PAGE_COUNT 81927.34 +7.35 +extern char *video_base;7.36 +7.37 +/* Determine pages of memory to save. Start walking from the render tilemap7.38 + * data and build up a page list7.39 + */7.40 +static void pvr2_find_referenced_pages( char *pages )7.41 +{7.42 + /* Dummy implementation - save everything */7.43 + memset( pages, 1, SAVE_PAGE_COUNT );7.44 +}7.45 +7.46 +/**7.47 + * Save the current rendering data to a file for later analysis.7.48 + * @return 0 on success, non-zero on failure.7.49 + */7.50 +int pvr2_render_save_scene( const gchar *filename )7.51 +{7.52 + struct header {7.53 + char magic[16];7.54 + uint32_t version;7.55 + uint32_t timestamp;7.56 + uint32_t frame_count;7.57 + } scene_header;7.58 +7.59 + char page_map[SAVE_PAGE_COUNT];7.60 + int i,j;7.61 + pvr2_find_referenced_pages(page_map);7.62 +7.63 + FILE *f = fopen( filename, "wo" );7.64 + if( f == NULL ) {7.65 + ERROR( "Unable to open file '%s' to write scene data: %s", filename, strerror(errno) );7.66 + return -1;7.67 + }7.68 +7.69 + /* Header */7.70 + memcpy( scene_header.magic, SCENE_SAVE_MAGIC, 16 );7.71 + scene_header.version = SCENE_SAVE_VERSION;7.72 + scene_header.timestamp = time(NULL);7.73 + scene_header.frame_count = pvr2_get_frame_count();7.74 + fwrite( &scene_header, sizeof(scene_header), 1, f );7.75 +7.76 + /* PVR2 registers - could probably be more specific, but doesn't7.77 + * really use a lot of space. Loader is assumed to know which7.78 + * registers actually need to be set.7.79 + */7.80 + fwrite( mmio_region_PVR2.mem, 0x1000, 1, f );7.81 + fwrite( mmio_region_PVR2PAL.mem, 0x1000, 1, f );7.82 +7.83 + /* Write out the VRAM pages we care about */7.84 + for( i=0; i<SAVE_PAGE_COUNT; i++ ) {7.85 + if( page_map[i] != 0 ) {7.86 + for( j=i+1; j<SAVE_PAGE_COUNT && page_map[j] != 0; j++ );7.87 + /* Write region from i..j-1 */7.88 + uint32_t start = i * SAVE_PAGE_SIZE;7.89 + uint32_t length = (j-i) * SAVE_PAGE_SIZE;7.90 + fwrite( &start, sizeof(uint32_t), 1, f );7.91 + fwrite( &length, sizeof(uint32_t), 1, f );7.92 + fwrite( video_base + start, 1, length, f );7.93 + i = j-1;7.94 + }7.95 + }7.96 + /* Write out the EOF marker */7.97 + uint32_t eof = 0xFFFFFFFF;7.98 + fwrite( &eof, sizeof(uint32_t), 1, f );7.99 + fclose( f );7.100 +}
.